• 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 <sys/types.h>
21 
22 #include <GLES2/gl2.h>
23 
24 #include <ui/Region.h>
25 
26 #include <SkPaint.h>
27 #include <SkXfermode.h>
28 
29 #include "Rect.h"
30 #include "RenderBuffer.h"
31 #include "SkiaColorFilter.h"
32 #include "Texture.h"
33 #include "Vertex.h"
34 
35 namespace android {
36 namespace uirenderer {
37 
38 ///////////////////////////////////////////////////////////////////////////////
39 // Layers
40 ///////////////////////////////////////////////////////////////////////////////
41 
42 // Forward declarations
43 class OpenGLRenderer;
44 class DisplayList;
45 class DeferredDisplayList;
46 class DeferStateStruct;
47 
48 /**
49  * A layer has dimensions and is backed by an OpenGL texture or FBO.
50  */
51 struct Layer {
52     Layer(const uint32_t layerWidth, const uint32_t layerHeight);
53     ~Layer();
54 
55     static uint32_t computeIdealWidth(uint32_t layerWidth);
56     static uint32_t computeIdealHeight(uint32_t layerHeight);
57 
58     /**
59      * Calling this method will remove (either by recycling or
60      * destroying) the associated FBO, if present, and any render
61      * buffer (stencil for instance.)
62      */
63     void removeFbo(bool flush = true);
64 
65     /**
66      * Sets this layer's region to a rectangle. Computes the appropriate
67      * texture coordinates.
68      */
setRegionAsRectLayer69     void setRegionAsRect() {
70         const android::Rect& bounds = region.getBounds();
71         regionRect.set(bounds.leftTop().x, bounds.leftTop().y,
72                bounds.rightBottom().x, bounds.rightBottom().y);
73 
74         const float texX = 1.0f / float(texture.width);
75         const float texY = 1.0f / float(texture.height);
76         const float height = layer.getHeight();
77         texCoords.set(
78                regionRect.left * texX, (height - regionRect.top) * texY,
79                regionRect.right * texX, (height - regionRect.bottom) * texY);
80 
81         regionRect.translate(layer.left, layer.top);
82     }
83 
updateDeferredLayer84     void updateDeferred(OpenGLRenderer* renderer, DisplayList* displayList,
85             int left, int top, int right, int bottom) {
86         this->renderer = renderer;
87         this->displayList = displayList;
88         const Rect r(left, top, right, bottom);
89         dirtyRect.unionWith(r);
90         deferredUpdateScheduled = true;
91     }
92 
getWidthLayer93     inline uint32_t getWidth() const {
94         return texture.width;
95     }
96 
getHeightLayer97     inline uint32_t getHeight() const {
98         return texture.height;
99     }
100 
101     /**
102      * Resize the layer and its texture if needed.
103      *
104      * @param width The new width of the layer
105      * @param height The new height of the layer
106      *
107      * @return True if the layer was resized or nothing happened, false if
108      *         a failure occurred during the resizing operation
109      */
110     bool resize(const uint32_t width, const uint32_t height);
111 
setSizeLayer112     void setSize(uint32_t width, uint32_t height) {
113         texture.width = width;
114         texture.height = height;
115     }
116 
117     ANDROID_API void setPaint(SkPaint* paint);
118 
setBlendLayer119     inline void setBlend(bool blend) {
120         texture.blend = blend;
121     }
122 
isBlendLayer123     inline bool isBlend() const {
124         return texture.blend;
125     }
126 
setAlphaLayer127     inline void setAlpha(int alpha) {
128         this->alpha = alpha;
129     }
130 
setAlphaLayer131     inline void setAlpha(int alpha, SkXfermode::Mode mode) {
132         this->alpha = alpha;
133         this->mode = mode;
134     }
135 
getAlphaLayer136     inline int getAlpha() const {
137         return alpha;
138     }
139 
getModeLayer140     inline SkXfermode::Mode getMode() const {
141         return mode;
142     }
143 
setEmptyLayer144     inline void setEmpty(bool empty) {
145         this->empty = empty;
146     }
147 
isEmptyLayer148     inline bool isEmpty() const {
149         return empty;
150     }
151 
setFboLayer152     inline void setFbo(GLuint fbo) {
153         this->fbo = fbo;
154     }
155 
getFboLayer156     inline GLuint getFbo() const {
157         return fbo;
158     }
159 
setStencilRenderBufferLayer160     inline void setStencilRenderBuffer(RenderBuffer* renderBuffer) {
161         if (RenderBuffer::isStencilBuffer(renderBuffer->getFormat())) {
162             this->stencil = renderBuffer;
163             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
164                     GL_RENDERBUFFER, stencil->getName());
165         } else {
166             ALOGE("The specified render buffer is not a stencil buffer");
167         }
168     }
169 
getStencilRenderBufferLayer170     inline RenderBuffer* getStencilRenderBuffer() const {
171         return stencil;
172     }
173 
getTextureLayer174     inline GLuint getTexture() const {
175         return texture.id;
176     }
177 
getRenderTargetLayer178     inline GLenum getRenderTarget() const {
179         return renderTarget;
180     }
181 
setRenderTargetLayer182     inline void setRenderTarget(GLenum renderTarget) {
183         this->renderTarget = renderTarget;
184     }
185 
186     void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
187         texture.setWrap(wrap, bindTexture, force, renderTarget);
188     }
189 
190     void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
191         texture.setFilter(filter, bindTexture, force, renderTarget);
192     }
193 
isCacheableLayer194     inline bool isCacheable() const {
195         return cacheable;
196     }
197 
setCacheableLayer198     inline void setCacheable(bool cacheable) {
199         this->cacheable = cacheable;
200     }
201 
isDirtyLayer202     inline bool isDirty() const {
203         return dirty;
204     }
205 
setDirtyLayer206     inline void setDirty(bool dirty) {
207         this->dirty = dirty;
208     }
209 
isTextureLayerLayer210     inline bool isTextureLayer() const {
211         return textureLayer;
212     }
213 
setTextureLayerLayer214     inline void setTextureLayer(bool textureLayer) {
215         this->textureLayer = textureLayer;
216     }
217 
getColorFilterLayer218     inline SkiaColorFilter* getColorFilter() const {
219         return colorFilter;
220     }
221 
222     ANDROID_API void setColorFilter(SkiaColorFilter* filter);
223 
bindTextureLayer224     inline void bindTexture() const {
225         if (texture.id) {
226             glBindTexture(renderTarget, texture.id);
227         }
228     }
229 
bindStencilRenderBufferLayer230     inline void bindStencilRenderBuffer() const {
231         if (stencil) {
232             stencil->bind();
233         }
234     }
235 
generateTextureLayer236     inline void generateTexture() {
237         if (!texture.id) {
238             glGenTextures(1, &texture.id);
239         }
240     }
241 
deleteTextureLayer242     inline void deleteTexture() {
243         if (texture.id) {
244             glDeleteTextures(1, &texture.id);
245             texture.id = 0;
246         }
247     }
248 
249     /**
250      * When the caller frees the texture itself, the caller
251      * must call this method to tell this layer that it lost
252      * the texture.
253      */
clearTextureLayer254     void clearTexture() {
255         texture.id = 0;
256     }
257 
allocateTextureLayer258     inline void allocateTexture() {
259 #if DEBUG_LAYERS
260         ALOGD("  Allocate layer: %dx%d", getWidth(), getHeight());
261 #endif
262         if (texture.id) {
263             glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
264             glTexImage2D(renderTarget, 0, GL_RGBA, getWidth(), getHeight(), 0,
265                     GL_RGBA, GL_UNSIGNED_BYTE, NULL);
266         }
267     }
268 
getTexTransformLayer269     inline mat4& getTexTransform() {
270         return texTransform;
271     }
272 
getTransformLayer273     inline mat4& getTransform() {
274         return transform;
275     }
276 
277     void defer();
278     void flush();
279     void render();
280 
281     /**
282      * Bounds of the layer.
283      */
284     Rect layer;
285     /**
286      * Texture coordinates of the layer.
287      */
288     Rect texCoords;
289     /**
290      * Clipping rectangle.
291      */
292     Rect clipRect;
293 
294     /**
295      * Dirty region indicating what parts of the layer
296      * have been drawn.
297      */
298     Region region;
299     /**
300      * If the region is a rectangle, coordinates of the
301      * region are stored here.
302      */
303     Rect regionRect;
304 
305     /**
306      * If the layer can be rendered as a mesh, this is non-null.
307      */
308     TextureVertex* mesh;
309     uint16_t* meshIndices;
310     GLsizei meshElementCount;
311 
312     /**
313      * Used for deferred updates.
314      */
315     bool deferredUpdateScheduled;
316     OpenGLRenderer* renderer;
317     DisplayList* displayList;
318     Rect dirtyRect;
319     bool debugDrawUpdate;
320     bool hasDrawnSinceUpdate;
321 
322 private:
323     /**
324      * Name of the FBO used to render the layer. If the name is 0
325      * this layer is not backed by an FBO, but a simple texture.
326      */
327     GLuint fbo;
328 
329     /**
330      * The render buffer used as the stencil buffer.
331      */
332     RenderBuffer* stencil;
333 
334     /**
335      * Indicates whether this layer has been used already.
336      */
337     bool empty;
338 
339     /**
340      * The texture backing this layer.
341      */
342     Texture texture;
343 
344     /**
345      * If set to true (by default), the layer can be reused.
346      */
347     bool cacheable;
348 
349     /**
350      * When set to true, this layer must be treated as a texture
351      * layer.
352      */
353     bool textureLayer;
354 
355     /**
356      * When set to true, this layer is dirty and should be cleared
357      * before any rendering occurs.
358      */
359     bool dirty;
360 
361     /**
362      * Indicates the render target.
363      */
364     GLenum renderTarget;
365 
366     /**
367      * Color filter used to draw this layer. Optional.
368      */
369     SkiaColorFilter* colorFilter;
370 
371     /**
372      * Opacity of the layer.
373      */
374     int alpha;
375     /**
376      * Blending mode of the layer.
377      */
378     SkXfermode::Mode mode;
379 
380     /**
381      * Optional texture coordinates transform.
382      */
383     mat4 texTransform;
384 
385     /**
386      * Optional transform.
387      */
388     mat4 transform;
389 
390     /**
391      * Used to defer display lists when the layer is updated with a
392      * display list.
393      */
394     DeferredDisplayList* deferredList;
395 
396 }; // struct Layer
397 
398 }; // namespace uirenderer
399 }; // namespace android
400 
401 #endif // ANDROID_HWUI_LAYER_H
402