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