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