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, uint8_t spotShadowAlpha)
50                 : ambientShadowAlpha(ambientShadowAlpha), spotShadowAlpha(spotShadowAlpha) {}
51         uint8_t ambientShadowAlpha;
52         uint8_t spotShadowAlpha;
53     };
54 
BakedOpRenderer(Caches & caches,RenderState & renderState,bool opaque,bool wideColorGamut,const LightInfo & lightInfo)55     BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque, bool wideColorGamut,
56                     const LightInfo& lightInfo)
57             : mGlopReceiver(DefaultGlopReceiver)
58             , mRenderState(renderState)
59             , mCaches(caches)
60             , mOpaque(opaque)
61             , mWideColorGamut(wideColorGamut)
62             , mLightInfo(lightInfo) {}
63 
renderState()64     RenderState& renderState() { return mRenderState; }
caches()65     Caches& caches() { return mCaches; }
66 
67     void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect);
68     void endFrame(const Rect& repaintRect);
69     WARN_UNUSED_RESULT OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height);
70     void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer);
71     void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect);
72     void endLayer();
73     WARN_UNUSED_RESULT OffscreenBuffer* copyToLayer(const Rect& area);
74 
75     Texture* getTexture(Bitmap* bitmap);
getLightInfo()76     const LightInfo& getLightInfo() const { return mLightInfo; }
77 
renderGlop(const BakedOpState & state,const Glop & glop)78     void renderGlop(const BakedOpState& state, const Glop& glop) {
79         renderGlop(&state.computedState.clippedBounds, state.computedState.getClipIfNeeded(), glop);
80     }
81     void renderFunctor(const FunctorOp& op, const BakedOpState& state);
82 
renderGlop(const Rect * dirtyBounds,const ClipBase * clip,const Glop & glop)83     void renderGlop(const Rect* dirtyBounds, const ClipBase* clip, const Glop& glop) {
84         mGlopReceiver(*this, dirtyBounds, clip, glop);
85     }
offscreenRenderTarget()86     bool offscreenRenderTarget() { return mRenderTarget.offscreenBuffer != nullptr; }
87     void dirtyRenderTarget(const Rect& dirtyRect);
didDraw()88     bool didDraw() const { return mHasDrawn; }
89 
getViewportWidth()90     uint32_t getViewportWidth() const { return mRenderTarget.viewportWidth; }
getViewportHeight()91     uint32_t getViewportHeight() const { return mRenderTarget.viewportHeight; }
92 
93     // simple draw methods, to be used for end frame decoration
drawRect(float left,float top,float right,float bottom,const SkPaint * paint)94     void drawRect(float left, float top, float right, float bottom, const SkPaint* paint) {
95         float ltrb[4] = {left, top, right, bottom};
96         drawRects(ltrb, 4, paint);
97     }
98     void drawRects(const float* rects, int count, const SkPaint* paint);
99 
100 protected:
101     GlopReceiver mGlopReceiver;
102 
103 private:
DefaultGlopReceiver(BakedOpRenderer & renderer,const Rect * dirtyBounds,const ClipBase * clip,const Glop & glop)104     static void DefaultGlopReceiver(BakedOpRenderer& renderer, const Rect* dirtyBounds,
105                                     const ClipBase* clip, const Glop& glop) {
106         renderer.renderGlopImpl(dirtyBounds, clip, glop);
107     }
108     void renderGlopImpl(const Rect* dirtyBounds, const ClipBase* clip, const Glop& glop);
109     void setViewport(uint32_t width, uint32_t height);
110     void clearColorBuffer(const Rect& clearRect);
111     void prepareRender(const Rect* dirtyBounds, const ClipBase* clip);
112     void setupStencilRectList(const ClipBase* clip);
113     void setupStencilRegion(const ClipBase* clip);
114     void setupStencilQuads(std::vector<Vertex>& quadVertices, int incrementThreshold);
115 
116     RenderState& mRenderState;
117     Caches& mCaches;
118     bool mOpaque;
119     bool mWideColorGamut;
120     bool mHasDrawn = false;
121 
122     // render target state - setup by start/end layer/frame
123     // only valid to use in between start/end pairs.
124     struct {
125         // If not drawing to a layer: fbo = 0, offscreenBuffer = null,
126         // Otherwise these refer to currently painting layer's state
127         GLuint frameBufferId = 0;
128         OffscreenBuffer* offscreenBuffer = nullptr;
129 
130         // Used when drawing to a layer and using stencil clipping. otherwise null.
131         RenderBuffer* stencil = nullptr;
132 
133         // value representing the ClipRectList* or ClipRegion* currently stored in
134         // the stencil of the current render target
135         const ClipBase* lastStencilClip = nullptr;
136 
137         // Size of renderable region in current render target - for layers, may not match actual
138         // bounds of FBO texture. offscreenBuffer->texture has this information.
139         uint32_t viewportWidth = 0;
140         uint32_t viewportHeight = 0;
141 
142         Matrix4 orthoMatrix;
143     } mRenderTarget;
144 
145     const LightInfo mLightInfo;
146 };
147 
148 };  // namespace uirenderer
149 };  // namespace android
150