• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <GpuMemoryTracker.h>
28 
29 #include <ui/Region.h>
30 
31 #include <SkPaint.h>
32 #include <SkXfermode.h>
33 
34 #include "Matrix.h"
35 #include "Rect.h"
36 #include "RenderBuffer.h"
37 #include "Texture.h"
38 #include "Vertex.h"
39 
40 namespace android {
41 namespace uirenderer {
42 
43 ///////////////////////////////////////////////////////////////////////////////
44 // Layers
45 ///////////////////////////////////////////////////////////////////////////////
46 
47 // Forward declarations
48 class Caches;
49 class RenderNode;
50 class RenderState;
51 class OpenGLRenderer;
52 class DeferredDisplayList;
53 struct DeferStateStruct;
54 
55 /**
56  * A layer has dimensions and is backed by an OpenGL texture or FBO.
57  */
58 class Layer : public VirtualLightRefBase, GpuMemoryTracker {
59 public:
60     enum class Type {
61         Texture,
62         DisplayList,
63     };
64 
65     // layer lifecycle, controlled from outside
66     enum class State {
67         Uncached = 0,
68         InCache = 1,
69         FailedToCache = 2,
70         RemovedFromCache = 3,
71         DeletedFromCache = 4,
72         InGarbageList = 5,
73     };
74     State state; // public for logging/debugging purposes
75 
76     Layer(Type type, RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight);
77     ~Layer();
78 
79     static uint32_t computeIdealWidth(uint32_t layerWidth);
80     static uint32_t computeIdealHeight(uint32_t layerHeight);
81 
82     /**
83      * Calling this method will remove (either by recycling or
84      * destroying) the associated FBO, if present, and any render
85      * buffer (stencil for instance.)
86      */
87     void removeFbo(bool flush = true);
88 
89     /**
90      * Sets this layer's region to a rectangle. Computes the appropriate
91      * texture coordinates.
92      */
setRegionAsRect()93     void setRegionAsRect() {
94         const android::Rect& bounds = region.getBounds();
95         regionRect.set(bounds.leftTop().x, bounds.leftTop().y,
96                bounds.rightBottom().x, bounds.rightBottom().y);
97 
98         const float texX = 1.0f / float(texture.mWidth);
99         const float texY = 1.0f / float(texture.mHeight);
100         const float height = layer.getHeight();
101         texCoords.set(
102                regionRect.left * texX, (height - regionRect.top) * texY,
103                regionRect.right * texX, (height - regionRect.bottom) * texY);
104 
105         regionRect.translate(layer.left, layer.top);
106     }
107 
setWindowTransform(Matrix4 & windowTransform)108     void setWindowTransform(Matrix4& windowTransform) {
109         cachedInvTransformInWindow.loadInverse(windowTransform);
110         rendererLightPosDirty = true;
111     }
112 
113     void updateDeferred(RenderNode* renderNode, int left, int top, int right, int bottom);
114 
getWidth()115     inline uint32_t getWidth() const {
116         return texture.mWidth;
117     }
118 
getHeight()119     inline uint32_t getHeight() const {
120         return texture.mHeight;
121     }
122 
123     /**
124      * Resize the layer and its texture if needed.
125      *
126      * @param width The new width of the layer
127      * @param height The new height of the layer
128      *
129      * @return True if the layer was resized or nothing happened, false if
130      *         a failure occurred during the resizing operation
131      */
132     bool resize(const uint32_t width, const uint32_t height);
133 
setSize(uint32_t width,uint32_t height)134     void setSize(uint32_t width, uint32_t height) {
135         texture.updateSize(width, height, texture.format());
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 
isRenderable()219     inline bool isRenderable() const {
220         return renderTarget != GL_NONE;
221     }
222 
223     void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
224         texture.setWrap(wrap, bindTexture, force, renderTarget);
225     }
226 
227     void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
228         texture.setFilter(filter, bindTexture, force, renderTarget);
229     }
230 
isCacheable()231     inline bool isCacheable() const {
232         return cacheable;
233     }
234 
setCacheable(bool cacheable)235     inline void setCacheable(bool cacheable) {
236         this->cacheable = cacheable;
237     }
238 
isDirty()239     inline bool isDirty() const {
240         return dirty;
241     }
242 
setDirty(bool dirty)243     inline void setDirty(bool dirty) {
244         this->dirty = dirty;
245     }
246 
isTextureLayer()247     inline bool isTextureLayer() const {
248         return type == Type::Texture;
249     }
250 
getColorFilter()251     inline SkColorFilter* getColorFilter() const {
252         return colorFilter;
253     }
254 
255     ANDROID_API void setColorFilter(SkColorFilter* filter);
256 
setConvexMask(const SkPath * convexMask)257     inline void setConvexMask(const SkPath* convexMask) {
258         this->convexMask = convexMask;
259     }
260 
getConvexMask()261     inline const SkPath* getConvexMask() {
262         return convexMask;
263     }
264 
265     void bindStencilRenderBuffer() const;
266 
267     void bindTexture() const;
268     void generateTexture();
269     void allocateTexture();
270 
271     /**
272      * When the caller frees the texture itself, the caller
273      * must call this method to tell this layer that it lost
274      * the texture.
275      */
276     ANDROID_API void clearTexture();
277 
getTexTransform()278     inline mat4& getTexTransform() {
279         return texTransform;
280     }
281 
getTransform()282     inline mat4& getTransform() {
283         return transform;
284     }
285 
286     void defer(const OpenGLRenderer& rootRenderer);
287     void cancelDefer();
288     void flush();
289     void render(const OpenGLRenderer& rootRenderer);
290 
291     /**
292      * Posts a decStrong call to the appropriate thread.
293      * Thread-safe.
294      */
295     void postDecStrong();
296 
297     /**
298      * Lost the GL context but the layer is still around, mark it invalid internally
299      * so the dtor knows not to do any GL work
300      */
301     void onGlContextLost();
302 
303     /**
304      * Bounds of the layer.
305      */
306     Rect layer;
307     /**
308      * Texture coordinates of the layer.
309      */
310     Rect texCoords;
311     /**
312      * Clipping rectangle.
313      */
314     Rect clipRect;
315 
316     /**
317      * Dirty region indicating what parts of the layer
318      * have been drawn.
319      */
320     Region region;
321     /**
322      * If the region is a rectangle, coordinates of the
323      * region are stored here.
324      */
325     Rect regionRect;
326 
327     /**
328      * If the layer can be rendered as a mesh, this is non-null.
329      */
330     TextureVertex* mesh = nullptr;
331     GLsizei meshElementCount = 0;
332 
333     /**
334      * Used for deferred updates.
335      */
336     bool deferredUpdateScheduled = false;
337     std::unique_ptr<OpenGLRenderer> renderer;
338     sp<RenderNode> renderNode;
339     Rect dirtyRect;
340     bool debugDrawUpdate = false;
341     bool hasDrawnSinceUpdate = false;
342     bool wasBuildLayered = false;
343 
344 private:
345     void requireRenderer();
346     void updateLightPosFromRenderer(const OpenGLRenderer& rootRenderer);
347 
348     Caches& caches;
349 
350     RenderState& renderState;
351 
352     /**
353      * Name of the FBO used to render the layer. If the name is 0
354      * this layer is not backed by an FBO, but a simple texture.
355      */
356     GLuint fbo = 0;
357 
358     /**
359      * The render buffer used as the stencil buffer.
360      */
361     RenderBuffer* stencil = nullptr;
362 
363     /**
364      * Indicates whether this layer has been used already.
365      */
366     bool empty = true;
367 
368     /**
369      * The texture backing this layer.
370      */
371     Texture texture;
372 
373     /**
374      * If set to true (by default), the layer can be reused.
375      */
376     bool cacheable = true;
377 
378     /**
379      * Denotes whether the layer is a DisplayList, or Texture layer.
380      */
381     const Type type;
382 
383     /**
384      * When set to true, this layer is dirty and should be cleared
385      * before any rendering occurs.
386      */
387     bool dirty = false;
388 
389     /**
390      * Indicates the render target.
391      */
392     GLenum renderTarget = GL_TEXTURE_2D;
393 
394     /**
395      * Color filter used to draw this layer. Optional.
396      */
397     SkColorFilter* colorFilter = nullptr;
398 
399     /**
400      * Indicates raster data backing the layer is scaled, requiring filtration.
401      */
402     bool forceFilter = false;
403 
404     /**
405      * Opacity of the layer.
406      */
407     int alpha = 255;
408 
409     /**
410      * Blending mode of the layer.
411      */
412     SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode;
413 
414     /**
415      * Optional texture coordinates transform.
416      */
417     mat4 texTransform;
418 
419     /**
420      * Optional transform.
421      */
422     mat4 transform;
423 
424     /**
425      * Cached transform of layer in window, updated only on creation / resize
426      */
427     mat4 cachedInvTransformInWindow;
428     bool rendererLightPosDirty = true;
429 
430     /**
431      * Used to defer display lists when the layer is updated with a
432      * display list.
433      */
434     std::unique_ptr<DeferredDisplayList> deferredList;
435 
436     /**
437      * This convex path should be used to mask the layer's draw to the screen.
438      *
439      * Data not owned/managed by layer object.
440      */
441     const SkPath* convexMask = nullptr;
442 
443 }; // struct Layer
444 
445 }; // namespace uirenderer
446 }; // namespace android
447 
448 #endif // ANDROID_HWUI_LAYER_H
449