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