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