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