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