1 /*
2  * Copyright (C) 2010 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 #ifndef ANDROID_HWUI_LAYER_H
18 #define ANDROID_HWUI_LAYER_H
19 
20 #include <cutils/compiler.h>
21 #include <sys/types.h>
22 #include <utils/StrongPointer.h>
23 #include <utils/RefBase.h>
24 #include <memory>
25 
26 #include <GLES2/gl2.h>
27 
28 #include <ui/Region.h>
29 
30 #include <SkPaint.h>
31 #include <SkXfermode.h>
32 
33 #include "Matrix.h"
34 #include "Rect.h"
35 #include "RenderBuffer.h"
36 #include "Texture.h"
37 #include "Vertex.h"
38 
39 namespace android {
40 namespace uirenderer {
41 
42 ///////////////////////////////////////////////////////////////////////////////
43 // Layers
44 ///////////////////////////////////////////////////////////////////////////////
45 
46 // Forward declarations
47 class Caches;
48 class RenderNode;
49 class RenderState;
50 class OpenGLRenderer;
51 class DeferredDisplayList;
52 struct DeferStateStruct;
53 
54 /**
55  * A layer has dimensions and is backed by an OpenGL texture or FBO.
56  */
57 class Layer : public VirtualLightRefBase {
58 public:
59     enum Type {
60         kType_Texture,
61         kType_DisplayList,
62     };
63 
64     // layer lifecycle, controlled from outside
65     enum State {
66         kState_Uncached = 0,
67         kState_InCache = 1,
68         kState_FailedToCache = 2,
69         kState_RemovedFromCache = 3,
70         kState_DeletedFromCache = 4,
71         kState_InGarbageList = 5,
72     };
73     State state; // public for logging/debugging purposes
74 
75     Layer(Type type, RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight);
76     ~Layer();
77 
78     static uint32_t computeIdealWidth(uint32_t layerWidth);
79     static uint32_t computeIdealHeight(uint32_t layerHeight);
80 
81     /**
82      * Calling this method will remove (either by recycling or
83      * destroying) the associated FBO, if present, and any render
84      * buffer (stencil for instance.)
85      */
86     void removeFbo(bool flush = true);
87 
88     /**
89      * Sets this layer's region to a rectangle. Computes the appropriate
90      * texture coordinates.
91      */
setRegionAsRect()92     void setRegionAsRect() {
93         const android::Rect& bounds = region.getBounds();
94         regionRect.set(bounds.leftTop().x, bounds.leftTop().y,
95                bounds.rightBottom().x, bounds.rightBottom().y);
96 
97         const float texX = 1.0f / float(texture.width);
98         const float texY = 1.0f / float(texture.height);
99         const float height = layer.getHeight();
100         texCoords.set(
101                regionRect.left * texX, (height - regionRect.top) * texY,
102                regionRect.right * texX, (height - regionRect.bottom) * texY);
103 
104         regionRect.translate(layer.left, layer.top);
105     }
106 
setWindowTransform(Matrix4 & windowTransform)107     void setWindowTransform(Matrix4& windowTransform) {
108         cachedInvTransformInWindow.loadInverse(windowTransform);
109         rendererLightPosDirty = true;
110     }
111 
112     void updateDeferred(RenderNode* renderNode, int left, int top, int right, int bottom);
113 
getWidth()114     inline uint32_t getWidth() const {
115         return texture.width;
116     }
117 
getHeight()118     inline uint32_t getHeight() const {
119         return texture.height;
120     }
121 
122     /**
123      * Resize the layer and its texture if needed.
124      *
125      * @param width The new width of the layer
126      * @param height The new height of the layer
127      *
128      * @return True if the layer was resized or nothing happened, false if
129      *         a failure occurred during the resizing operation
130      */
131     bool resize(const uint32_t width, const uint32_t height);
132 
setSize(uint32_t width,uint32_t height)133     void setSize(uint32_t width, uint32_t height) {
134         texture.width = width;
135         texture.height = height;
136     }
137 
138     ANDROID_API void setPaint(const SkPaint* paint);
139 
setBlend(bool blend)140     inline void setBlend(bool blend) {
141         texture.blend = blend;
142     }
143 
isBlend()144     inline bool isBlend() const {
145         return texture.blend;
146     }
147 
setForceFilter(bool forceFilter)148     inline void setForceFilter(bool forceFilter) {
149         this->forceFilter = forceFilter;
150     }
151 
getForceFilter()152     inline bool getForceFilter() const {
153         return forceFilter;
154     }
155 
setAlpha(int alpha)156     inline void setAlpha(int alpha) {
157         this->alpha = alpha;
158     }
159 
setAlpha(int alpha,SkXfermode::Mode mode)160     inline void setAlpha(int alpha, SkXfermode::Mode mode) {
161         this->alpha = alpha;
162         this->mode = mode;
163     }
164 
getAlpha()165     inline int getAlpha() const {
166         return alpha;
167     }
168 
getMode()169     inline SkXfermode::Mode getMode() const {
170         return mode;
171     }
172 
setEmpty(bool empty)173     inline void setEmpty(bool empty) {
174         this->empty = empty;
175     }
176 
isEmpty()177     inline bool isEmpty() const {
178         return empty;
179     }
180 
setFbo(GLuint fbo)181     inline void setFbo(GLuint fbo) {
182         this->fbo = fbo;
183     }
184 
getFbo()185     inline GLuint getFbo() const {
186         return fbo;
187     }
188 
setStencilRenderBuffer(RenderBuffer * renderBuffer)189     inline void setStencilRenderBuffer(RenderBuffer* renderBuffer) {
190         if (RenderBuffer::isStencilBuffer(renderBuffer->getFormat())) {
191             this->stencil = renderBuffer;
192             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
193                     GL_RENDERBUFFER, stencil->getName());
194         } else {
195             ALOGE("The specified render buffer is not a stencil buffer");
196         }
197     }
198 
getStencilRenderBuffer()199     inline RenderBuffer* getStencilRenderBuffer() const {
200         return stencil;
201     }
202 
getTextureId()203     inline GLuint getTextureId() const {
204         return texture.id;
205     }
206 
getTexture()207     inline Texture& getTexture() {
208         return texture;
209     }
210 
getRenderTarget()211     inline GLenum getRenderTarget() const {
212         return renderTarget;
213     }
214 
setRenderTarget(GLenum renderTarget)215     inline void setRenderTarget(GLenum renderTarget) {
216         this->renderTarget = renderTarget;
217     }
218 
219     void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
220         texture.setWrap(wrap, bindTexture, force, renderTarget);
221     }
222 
223     void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
224         texture.setFilter(filter, bindTexture, force, renderTarget);
225     }
226 
isCacheable()227     inline bool isCacheable() const {
228         return cacheable;
229     }
230 
setCacheable(bool cacheable)231     inline void setCacheable(bool cacheable) {
232         this->cacheable = cacheable;
233     }
234 
isDirty()235     inline bool isDirty() const {
236         return dirty;
237     }
238 
setDirty(bool dirty)239     inline void setDirty(bool dirty) {
240         this->dirty = dirty;
241     }
242 
isTextureLayer()243     inline bool isTextureLayer() const {
244         return type == kType_Texture;
245     }
246 
getColorFilter()247     inline SkColorFilter* getColorFilter() const {
248         return colorFilter;
249     }
250 
251     ANDROID_API void setColorFilter(SkColorFilter* filter);
252 
setConvexMask(const SkPath * convexMask)253     inline void setConvexMask(const SkPath* convexMask) {
254         this->convexMask = convexMask;
255     }
256 
getConvexMask()257     inline const SkPath* getConvexMask() {
258         return convexMask;
259     }
260 
261     void bindStencilRenderBuffer() const;
262 
263     void bindTexture() const;
264     void generateTexture();
265     void allocateTexture();
266     void deleteTexture();
267 
268     /**
269      * When the caller frees the texture itself, the caller
270      * must call this method to tell this layer that it lost
271      * the texture.
272      */
273     ANDROID_API void clearTexture();
274 
getTexTransform()275     inline mat4& getTexTransform() {
276         return texTransform;
277     }
278 
getTransform()279     inline mat4& getTransform() {
280         return transform;
281     }
282 
283     void defer(const OpenGLRenderer& rootRenderer);
284     void cancelDefer();
285     void flush();
286     void render(const OpenGLRenderer& rootRenderer);
287 
288     /**
289      * Posts a decStrong call to the appropriate thread.
290      * Thread-safe.
291      */
292     void postDecStrong();
293 
294     /**
295      * Lost the GL context but the layer is still around, mark it invalid internally
296      * so the dtor knows not to do any GL work
297      */
298     void onGlContextLost();
299 
300     /**
301      * Bounds of the layer.
302      */
303     Rect layer;
304     /**
305      * Texture coordinates of the layer.
306      */
307     Rect texCoords;
308     /**
309      * Clipping rectangle.
310      */
311     Rect clipRect;
312 
313     /**
314      * Dirty region indicating what parts of the layer
315      * have been drawn.
316      */
317     Region region;
318     /**
319      * If the region is a rectangle, coordinates of the
320      * region are stored here.
321      */
322     Rect regionRect;
323 
324     /**
325      * If the layer can be rendered as a mesh, this is non-null.
326      */
327     TextureVertex* mesh = nullptr;
328     GLsizei meshElementCount = 0;
329 
330     /**
331      * Used for deferred updates.
332      */
333     bool deferredUpdateScheduled = false;
334     std::unique_ptr<OpenGLRenderer> renderer;
335     sp<RenderNode> renderNode;
336     Rect dirtyRect;
337     bool debugDrawUpdate = false;
338     bool hasDrawnSinceUpdate = false;
339     bool wasBuildLayered = false;
340 
341 private:
342     void requireRenderer();
343     void updateLightPosFromRenderer(const OpenGLRenderer& rootRenderer);
344 
345     Caches& caches;
346 
347     RenderState& renderState;
348 
349     /**
350      * Name of the FBO used to render the layer. If the name is 0
351      * this layer is not backed by an FBO, but a simple texture.
352      */
353     GLuint fbo = 0;
354 
355     /**
356      * The render buffer used as the stencil buffer.
357      */
358     RenderBuffer* stencil = nullptr;
359 
360     /**
361      * Indicates whether this layer has been used already.
362      */
363     bool empty = true;
364 
365     /**
366      * The texture backing this layer.
367      */
368     Texture texture;
369 
370     /**
371      * If set to true (by default), the layer can be reused.
372      */
373     bool cacheable = true;
374 
375     /**
376      * Denotes whether the layer is a DisplayList, or Texture layer.
377      */
378     const Type type;
379 
380     /**
381      * When set to true, this layer is dirty and should be cleared
382      * before any rendering occurs.
383      */
384     bool dirty = false;
385 
386     /**
387      * Indicates the render target.
388      */
389     GLenum renderTarget = GL_TEXTURE_2D;
390 
391     /**
392      * Color filter used to draw this layer. Optional.
393      */
394     SkColorFilter* colorFilter = nullptr;
395 
396     /**
397      * Indicates raster data backing the layer is scaled, requiring filtration.
398      */
399     bool forceFilter = false;
400 
401     /**
402      * Opacity of the layer.
403      */
404     int alpha = 255;
405 
406     /**
407      * Blending mode of the layer.
408      */
409     SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode;
410 
411     /**
412      * Optional texture coordinates transform.
413      */
414     mat4 texTransform;
415 
416     /**
417      * Optional transform.
418      */
419     mat4 transform;
420 
421     /**
422      * Cached transform of layer in window, updated only on creation / resize
423      */
424     mat4 cachedInvTransformInWindow;
425     bool rendererLightPosDirty = true;
426 
427     /**
428      * Used to defer display lists when the layer is updated with a
429      * display list.
430      */
431     std::unique_ptr<DeferredDisplayList> deferredList;
432 
433     /**
434      * This convex path should be used to mask the layer's draw to the screen.
435      *
436      * Data not owned/managed by layer object.
437      */
438     const SkPath* convexMask = nullptr;
439 
440 }; // struct Layer
441 
442 }; // namespace uirenderer
443 }; // namespace android
444 
445 #endif // ANDROID_HWUI_LAYER_H
446