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