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