Layer.h revision 0908764b2b3cf5075df4178a5f0a8547dcb7b317
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
35namespace android {
36namespace uirenderer {
37
38///////////////////////////////////////////////////////////////////////////////
39// Layers
40///////////////////////////////////////////////////////////////////////////////
41
42// Forward declarations
43class OpenGLRenderer;
44class DisplayList;
45class DeferredDisplayList;
46class DeferStateStruct;
47
48/**
49 * A layer has dimensions and is backed by an OpenGL texture or FBO.
50 */
51struct 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     */
69    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
84    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
93    inline uint32_t getWidth() const {
94        return texture.width;
95    }
96
97    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
112    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
119    inline void setBlend(bool blend) {
120        texture.blend = blend;
121    }
122
123    inline bool isBlend() const {
124        return texture.blend;
125    }
126
127    inline void setAlpha(int alpha) {
128        this->alpha = alpha;
129    }
130
131    inline void setAlpha(int alpha, SkXfermode::Mode mode) {
132        this->alpha = alpha;
133        this->mode = mode;
134    }
135
136    inline int getAlpha() const {
137        return alpha;
138    }
139
140    inline SkXfermode::Mode getMode() const {
141        return mode;
142    }
143
144    inline void setEmpty(bool empty) {
145        this->empty = empty;
146    }
147
148    inline bool isEmpty() const {
149        return empty;
150    }
151
152    inline void setFbo(GLuint fbo) {
153        this->fbo = fbo;
154    }
155
156    inline GLuint getFbo() const {
157        return fbo;
158    }
159
160    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
170    inline RenderBuffer* getStencilRenderBuffer() const {
171        return stencil;
172    }
173
174    inline GLuint getTexture() const {
175        return texture.id;
176    }
177
178    inline GLenum getRenderTarget() const {
179        return renderTarget;
180    }
181
182    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
194    inline bool isCacheable() const {
195        return cacheable;
196    }
197
198    inline void setCacheable(bool cacheable) {
199        this->cacheable = cacheable;
200    }
201
202    inline bool isDirty() const {
203        return dirty;
204    }
205
206    inline void setDirty(bool dirty) {
207        this->dirty = dirty;
208    }
209
210    inline bool isTextureLayer() const {
211        return textureLayer;
212    }
213
214    inline void setTextureLayer(bool textureLayer) {
215        this->textureLayer = textureLayer;
216    }
217
218    inline SkiaColorFilter* getColorFilter() const {
219        return colorFilter;
220    }
221
222    ANDROID_API void setColorFilter(SkiaColorFilter* filter);
223
224    inline void bindTexture() const {
225        if (texture.id) {
226            glBindTexture(renderTarget, texture.id);
227        }
228    }
229
230    inline void bindStencilRenderBuffer() const {
231        if (stencil) {
232            stencil->bind();
233        }
234    }
235
236    inline void generateTexture() {
237        if (!texture.id) {
238            glGenTextures(1, &texture.id);
239        }
240    }
241
242    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     */
254    void clearTexture() {
255        texture.id = 0;
256    }
257
258    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
269    inline mat4& getTexTransform() {
270        return texTransform;
271    }
272
273    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
321private:
322    /**
323     * Name of the FBO used to render the layer. If the name is 0
324     * this layer is not backed by an FBO, but a simple texture.
325     */
326    GLuint fbo;
327
328    /**
329     * The render buffer used as the stencil buffer.
330     */
331    RenderBuffer* stencil;
332
333    /**
334     * Indicates whether this layer has been used already.
335     */
336    bool empty;
337
338    /**
339     * The texture backing this layer.
340     */
341    Texture texture;
342
343    /**
344     * If set to true (by default), the layer can be reused.
345     */
346    bool cacheable;
347
348    /**
349     * When set to true, this layer must be treated as a texture
350     * layer.
351     */
352    bool textureLayer;
353
354    /**
355     * When set to true, this layer is dirty and should be cleared
356     * before any rendering occurs.
357     */
358    bool dirty;
359
360    /**
361     * Indicates the render target.
362     */
363    GLenum renderTarget;
364
365    /**
366     * Color filter used to draw this layer. Optional.
367     */
368    SkiaColorFilter* colorFilter;
369
370    /**
371     * Opacity of the layer.
372     */
373    int alpha;
374    /**
375     * Blending mode of the layer.
376     */
377    SkXfermode::Mode mode;
378
379    /**
380     * Optional texture coordinates transform.
381     */
382    mat4 texTransform;
383
384    /**
385     * Optional transform.
386     */
387    mat4 transform;
388
389    /**
390     * Used to defer display lists when the layer is updated with a
391     * display list.
392     */
393    DeferredDisplayList* deferredList;
394
395}; // struct Layer
396
397}; // namespace uirenderer
398}; // namespace android
399
400#endif // ANDROID_HWUI_LAYER_H
401