• 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 <SkXfermode.h>
27 
28 #include "Rect.h"
29 #include "SkiaColorFilter.h"
30 #include "Texture.h"
31 #include "Vertex.h"
32 
33 namespace android {
34 namespace uirenderer {
35 
36 ///////////////////////////////////////////////////////////////////////////////
37 // Layers
38 ///////////////////////////////////////////////////////////////////////////////
39 
40 // Forward declarations
41 class OpenGLRenderer;
42 class DisplayList;
43 
44 /**
45  * A layer has dimensions and is backed by an OpenGL texture or FBO.
46  */
47 struct Layer {
48     Layer(const uint32_t layerWidth, const uint32_t layerHeight);
49     ~Layer();
50 
51     void removeFbo();
52 
53     /**
54      * Sets this layer's region to a rectangle. Computes the appropriate
55      * texture coordinates.
56      */
setRegionAsRectLayer57     void setRegionAsRect() {
58         const android::Rect& bounds = region.getBounds();
59         regionRect.set(bounds.leftTop().x, bounds.leftTop().y,
60                bounds.rightBottom().x, bounds.rightBottom().y);
61 
62         const float texX = 1.0f / float(texture.width);
63         const float texY = 1.0f / float(texture.height);
64         const float height = layer.getHeight();
65         texCoords.set(
66                regionRect.left * texX, (height - regionRect.top) * texY,
67                regionRect.right * texX, (height - regionRect.bottom) * texY);
68 
69         regionRect.translate(layer.left, layer.top);
70     }
71 
updateDeferredLayer72     void updateDeferred(OpenGLRenderer* renderer, DisplayList* displayList,
73             int left, int top, int right, int bottom) {
74         this->renderer = renderer;
75         this->displayList = displayList;
76         const Rect r(left, top, right, bottom);
77         dirtyRect.unionWith(r);
78         deferredUpdateScheduled = true;
79     }
80 
getWidthLayer81     inline uint32_t getWidth() {
82         return texture.width;
83     }
84 
getHeightLayer85     inline uint32_t getHeight() {
86         return texture.height;
87     }
88 
setSizeLayer89     void setSize(uint32_t width, uint32_t height) {
90         texture.width = width;
91         texture.height = height;
92     }
93 
94     ANDROID_API void setPaint(SkPaint* paint);
95 
setBlendLayer96     inline void setBlend(bool blend) {
97         texture.blend = blend;
98     }
99 
isBlendLayer100     inline bool isBlend() {
101         return texture.blend;
102     }
103 
setAlphaLayer104     inline void setAlpha(int alpha) {
105         this->alpha = alpha;
106     }
107 
setAlphaLayer108     inline void setAlpha(int alpha, SkXfermode::Mode mode) {
109         this->alpha = alpha;
110         this->mode = mode;
111     }
112 
getAlphaLayer113     inline int getAlpha() {
114         return alpha;
115     }
116 
getModeLayer117     inline SkXfermode::Mode getMode() {
118         return mode;
119     }
120 
setEmptyLayer121     inline void setEmpty(bool empty) {
122         this->empty = empty;
123     }
124 
isEmptyLayer125     inline bool isEmpty() {
126         return empty;
127     }
128 
setFboLayer129     inline void setFbo(GLuint fbo) {
130         this->fbo = fbo;
131     }
132 
getFboLayer133     inline GLuint getFbo() {
134         return fbo;
135     }
136 
getTextureLayer137     inline GLuint getTexture() {
138         return texture.id;
139     }
140 
getRenderTargetLayer141     inline GLenum getRenderTarget() {
142         return renderTarget;
143     }
144 
setRenderTargetLayer145     inline void setRenderTarget(GLenum renderTarget) {
146         this->renderTarget = renderTarget;
147     }
148 
149     void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
150         texture.setWrap(wrap, bindTexture, force, renderTarget);
151     }
152 
153     void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
154         texture.setFilter(filter, bindTexture, force, renderTarget);
155     }
156 
isCacheableLayer157     inline bool isCacheable() {
158         return cacheable;
159     }
160 
setCacheableLayer161     inline void setCacheable(bool cacheable) {
162         this->cacheable = cacheable;
163     }
164 
isDirtyLayer165     inline bool isDirty() {
166         return dirty;
167     }
168 
setDirtyLayer169     inline void setDirty(bool dirty) {
170         this->dirty = dirty;
171     }
172 
isTextureLayerLayer173     inline bool isTextureLayer() {
174         return textureLayer;
175     }
176 
setTextureLayerLayer177     inline void setTextureLayer(bool textureLayer) {
178         this->textureLayer = textureLayer;
179     }
180 
getColorFilterLayer181     inline SkiaColorFilter* getColorFilter() {
182         return colorFilter;
183     }
184 
185     ANDROID_API void setColorFilter(SkiaColorFilter* filter);
186 
bindTextureLayer187     inline void bindTexture() {
188         if (texture.id) {
189             glBindTexture(renderTarget, texture.id);
190         }
191     }
192 
generateTextureLayer193     inline void generateTexture() {
194         if (!texture.id) {
195             glGenTextures(1, &texture.id);
196         }
197     }
198 
deleteTextureLayer199     inline void deleteTexture() {
200         if (texture.id) {
201             glDeleteTextures(1, &texture.id);
202             texture.id = 0;
203         }
204     }
205 
206     /**
207      * When the caller frees the texture itself, the caller
208      * must call this method to tell this layer that it lost
209      * the texture.
210      */
clearTextureLayer211     void clearTexture() {
212         texture.id = 0;
213     }
214 
deleteFboLayer215     inline void deleteFbo() {
216         if (fbo) glDeleteFramebuffers(1, &fbo);
217     }
218 
allocateTextureLayer219     inline void allocateTexture(GLenum format, GLenum storage) {
220 #if DEBUG_LAYERS
221         ALOGD("  Allocate layer: %dx%d", getWidth(), getHeight());
222 #endif
223         glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0, format, storage, NULL);
224     }
225 
getTexTransformLayer226     inline mat4& getTexTransform() {
227         return texTransform;
228     }
229 
getTransformLayer230     inline mat4& getTransform() {
231         return transform;
232     }
233 
234     /**
235      * Bounds of the layer.
236      */
237     Rect layer;
238     /**
239      * Texture coordinates of the layer.
240      */
241     Rect texCoords;
242 
243     /**
244      * Dirty region indicating what parts of the layer
245      * have been drawn.
246      */
247     Region region;
248     /**
249      * If the region is a rectangle, coordinates of the
250      * region are stored here.
251      */
252     Rect regionRect;
253 
254     /**
255      * If the layer can be rendered as a mesh, this is non-null.
256      */
257     TextureVertex* mesh;
258     uint16_t* meshIndices;
259     GLsizei meshElementCount;
260 
261     /**
262      * Used for deferred updates.
263      */
264     bool deferredUpdateScheduled;
265     OpenGLRenderer* renderer;
266     DisplayList* displayList;
267     Rect dirtyRect;
268 
269 private:
270     /**
271      * Name of the FBO used to render the layer. If the name is 0
272      * this layer is not backed by an FBO, but a simple texture.
273      */
274     GLuint fbo;
275 
276     /**
277      * Indicates whether this layer has been used already.
278      */
279     bool empty;
280 
281     /**
282      * The texture backing this layer.
283      */
284     Texture texture;
285 
286     /**
287      * If set to true (by default), the layer can be reused.
288      */
289     bool cacheable;
290 
291     /**
292      * When set to true, this layer must be treated as a texture
293      * layer.
294      */
295     bool textureLayer;
296 
297     /**
298      * When set to true, this layer is dirty and should be cleared
299      * before any rendering occurs.
300      */
301     bool dirty;
302 
303     /**
304      * Indicates the render target.
305      */
306     GLenum renderTarget;
307 
308     /**
309      * Color filter used to draw this layer. Optional.
310      */
311     SkiaColorFilter* colorFilter;
312 
313     /**
314      * Opacity of the layer.
315      */
316     int alpha;
317     /**
318      * Blending mode of the layer.
319      */
320     SkXfermode::Mode mode;
321 
322     /**
323      * Optional texture coordinates transform.
324      */
325     mat4 texTransform;
326 
327     /**
328      * Optional transform.
329      */
330     mat4 transform;
331 
332 }; // struct Layer
333 
334 }; // namespace uirenderer
335 }; // namespace android
336 
337 #endif // ANDROID_HWUI_LAYER_H
338