1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include "BakedOpState.h"
20 #include "Matrix.h"
21 #include "utils/Macros.h"
22 
23 namespace android {
24 namespace uirenderer {
25 
26 class Caches;
27 struct Glop;
28 class Layer;
29 class RenderState;
30 struct ClipBase;
31 
32 /**
33  * Main rendering manager for a collection of work - one frame + any contained FBOs.
34  *
35  * Manages frame and FBO lifecycle, binding the GL framebuffer as appropriate. This is the only
36  * place where FBOs are bound, created, and destroyed.
37  *
38  * All rendering operations will be sent by the Dispatcher, a collection of static methods,
39  * which has intentionally limited access to the renderer functionality.
40  */
41 class BakedOpRenderer {
42 public:
43     typedef void (*GlopReceiver)(BakedOpRenderer&, const Rect*, const ClipBase*, const Glop&);
44     /**
45      * Position agnostic shadow lighting info. Used with all shadow ops in scene.
46      */
47     struct LightInfo {
LightInfoLightInfo48         LightInfo() : LightInfo(0, 0) {}
LightInfoLightInfo49         LightInfo(uint8_t ambientShadowAlpha,
50                 uint8_t spotShadowAlpha)
51                 : ambientShadowAlpha(ambientShadowAlpha)
52                 , spotShadowAlpha(spotShadowAlpha) {}
53         uint8_t ambientShadowAlpha;
54         uint8_t spotShadowAlpha;
55     };
56 
BakedOpRenderer(Caches & caches,RenderState & renderState,bool opaque,const LightInfo & lightInfo)57     BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque,
58             const LightInfo& lightInfo)
59             : mGlopReceiver(DefaultGlopReceiver)
60             , mRenderState(renderState)
61             , mCaches(caches)
62             , mOpaque(opaque)
63             , mLightInfo(lightInfo) {
64     }
65 
renderState()66     RenderState& renderState() { return mRenderState; }
caches()67     Caches& caches() { return mCaches; }
68 
69     void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect);
70     void endFrame(const Rect& repaintRect);
71     WARN_UNUSED_RESULT OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height);
72     void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer);
73     void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect);
74     void endLayer();
75     WARN_UNUSED_RESULT OffscreenBuffer* copyToLayer(const Rect& area);
76 
77     Texture* getTexture(const SkBitmap* bitmap);
getLightInfo()78     const LightInfo& getLightInfo() const { return mLightInfo; }
79 
renderGlop(const BakedOpState & state,const Glop & glop)80     void renderGlop(const BakedOpState& state, const Glop& glop) {
81         renderGlop(&state.computedState.clippedBounds,
82                 state.computedState.getClipIfNeeded(),
83                 glop);
84     }
85     void renderFunctor(const FunctorOp& op, const BakedOpState& state);
86 
renderGlop(const Rect * dirtyBounds,const ClipBase * clip,const Glop & glop)87     void renderGlop(const Rect* dirtyBounds, const ClipBase* clip, const Glop& glop) {
88         mGlopReceiver(*this, dirtyBounds, clip, glop);
89     }
offscreenRenderTarget()90     bool offscreenRenderTarget() { return mRenderTarget.offscreenBuffer != nullptr; }
91     void dirtyRenderTarget(const Rect& dirtyRect);
didDraw()92     bool didDraw() const { return mHasDrawn; }
93 
getViewportWidth()94     uint32_t getViewportWidth() const { return mRenderTarget.viewportWidth; }
getViewportHeight()95     uint32_t getViewportHeight() const { return mRenderTarget.viewportHeight; }
96 
97     // simple draw methods, to be used for end frame decoration
drawRect(float left,float top,float right,float bottom,const SkPaint * paint)98     void drawRect(float left, float top, float right, float bottom, const SkPaint* paint) {
99         float ltrb[4] = { left, top, right, bottom };
100         drawRects(ltrb, 4, paint);
101     }
102     void drawRects(const float* rects, int count, const SkPaint* paint);
103 protected:
104     GlopReceiver mGlopReceiver;
105 private:
DefaultGlopReceiver(BakedOpRenderer & renderer,const Rect * dirtyBounds,const ClipBase * clip,const Glop & glop)106     static void DefaultGlopReceiver(BakedOpRenderer& renderer, const Rect* dirtyBounds,
107             const ClipBase* clip, const Glop& glop) {
108         renderer.renderGlopImpl(dirtyBounds, clip, glop);
109     }
110     void renderGlopImpl(const Rect* dirtyBounds, const ClipBase* clip, const Glop& glop);
111     void setViewport(uint32_t width, uint32_t height);
112     void clearColorBuffer(const Rect& clearRect);
113     void prepareRender(const Rect* dirtyBounds, const ClipBase* clip);
114     void setupStencilRectList(const ClipBase* clip);
115     void setupStencilRegion(const ClipBase* clip);
116     void setupStencilQuads(std::vector<Vertex>& quadVertices, int incrementThreshold);
117 
118     RenderState& mRenderState;
119     Caches& mCaches;
120     bool mOpaque;
121     bool mHasDrawn = false;
122 
123     // render target state - setup by start/end layer/frame
124     // only valid to use in between start/end pairs.
125     struct {
126         // If not drawing to a layer: fbo = 0, offscreenBuffer = null,
127         // Otherwise these refer to currently painting layer's state
128         GLuint frameBufferId = 0;
129         OffscreenBuffer* offscreenBuffer = nullptr;
130 
131         // Used when drawing to a layer and using stencil clipping. otherwise null.
132         RenderBuffer* stencil = nullptr;
133 
134         // value representing the ClipRectList* or ClipRegion* currently stored in
135         // the stencil of the current render target
136         const ClipBase* lastStencilClip = nullptr;
137 
138         // Size of renderable region in current render target - for layers, may not match actual
139         // bounds of FBO texture. offscreenBuffer->texture has this information.
140         uint32_t viewportWidth = 0;
141         uint32_t viewportHeight = 0;
142 
143         Matrix4 orthoMatrix;
144     } mRenderTarget;
145 
146     const LightInfo mLightInfo;
147 };
148 
149 }; // namespace uirenderer
150 }; // namespace android
151