blob: 3c2d80de3a79f540ea0ec1afc6bfa70936889d7f [file] [log] [blame]
Romain Guydda57022010-07-06 11:39:32 -07001/*
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
Romain Guy5b3b3522010-10-27 18:57:51 -070017#ifndef ANDROID_HWUI_LAYER_H
18#define ANDROID_HWUI_LAYER_H
Romain Guydda57022010-07-06 11:39:32 -070019
Romain Guyf7f93552010-07-08 19:17:03 -070020#include <sys/types.h>
21
Romain Guydda57022010-07-06 11:39:32 -070022#include <GLES2/gl2.h>
23
Romain Guy5b3b3522010-10-27 18:57:51 -070024#include <ui/Region.h>
25
Romain Guydda57022010-07-06 11:39:32 -070026#include <SkXfermode.h>
27
28#include "Rect.h"
Romain Guy171c5922011-01-06 10:04:23 -080029#include "SkiaColorFilter.h"
Romain Guy9ace8f52011-07-07 20:50:11 -070030#include "Texture.h"
Romain Guyf219da52011-01-16 12:54:25 -080031#include "Vertex.h"
Romain Guydda57022010-07-06 11:39:32 -070032
33namespace android {
34namespace uirenderer {
35
Romain Guy8550c4c2010-10-08 15:49:53 -070036///////////////////////////////////////////////////////////////////////////////
37// Layers
38///////////////////////////////////////////////////////////////////////////////
Romain Guydda57022010-07-06 11:39:32 -070039
40/**
Romain Guyeb993562010-10-05 18:14:38 -070041 * A layer has dimensions and is backed by an OpenGL texture or FBO.
Romain Guydda57022010-07-06 11:39:32 -070042 */
43struct Layer {
Romain Guy9ace8f52011-07-07 20:50:11 -070044 Layer(const uint32_t layerWidth, const uint32_t layerHeight) {
Romain Guyf219da52011-01-16 12:54:25 -080045 mesh = NULL;
46 meshIndices = NULL;
47 meshElementCount = 0;
Romain Guy9ace8f52011-07-07 20:50:11 -070048 cacheable = true;
49 textureLayer = false;
Romain Guy8f0095c2011-05-02 17:24:22 -070050 renderTarget = GL_TEXTURE_2D;
Romain Guy9ace8f52011-07-07 20:50:11 -070051 texture.width = layerWidth;
52 texture.height = layerHeight;
53 colorFilter = NULL;
54 firstFilter = true;
55 firstWrap = true;
Romain Guyf219da52011-01-16 12:54:25 -080056 }
57
58 ~Layer() {
59 if (mesh) delete mesh;
60 if (meshIndices) delete meshIndices;
Romain Guy8550c4c2010-10-08 15:49:53 -070061 }
62
Romain Guydda57022010-07-06 11:39:32 -070063 /**
Romain Guy9fc27812011-04-27 14:21:41 -070064 * 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
Romain Guy9ace8f52011-07-07 20:50:11 -070072 const float texX = 1.0f / float(texture.width);
73 const float texY = 1.0f / float(texture.height);
Romain Guy9fc27812011-04-27 14:21:41 -070074 const float height = layer.getHeight();
75 texCoords.set(
76 regionRect.left * texX, (height - regionRect.top) * texY,
77 regionRect.right * texX, (height - regionRect.bottom) * texY);
Romain Guy9ace8f52011-07-07 20:50:11 -070078
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;
Romain Guy9fc27812011-04-27 14:21:41 -0700218 }
219
220 /**
Romain Guy8550c4c2010-10-08 15:49:53 -0700221 * Bounds of the layer.
Romain Guydda57022010-07-06 11:39:32 -0700222 */
223 Rect layer;
224 /**
Romain Guy8550c4c2010-10-08 15:49:53 -0700225 * Texture coordinates of the layer.
Romain Guydda57022010-07-06 11:39:32 -0700226 */
Romain Guy8550c4c2010-10-08 15:49:53 -0700227 Rect texCoords;
228
Romain Guydda57022010-07-06 11:39:32 -0700229 /**
Romain Guy5b3b3522010-10-27 18:57:51 -0700230 * Dirty region indicating what parts of the layer
231 * have been drawn.
232 */
233 Region region;
Romain Guy40667672011-03-18 14:34:03 -0700234 /**
235 * If the region is a rectangle, coordinates of the
236 * region are stored here.
237 */
238 Rect regionRect;
Romain Guy171c5922011-01-06 10:04:23 -0800239
240 /**
Romain Guyf219da52011-01-16 12:54:25 -0800241 * If the layer can be rendered as a mesh, this is non-null.
242 */
243 TextureVertex* mesh;
244 uint16_t* meshIndices;
245 GLsizei meshElementCount;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700246
Romain Guy9ace8f52011-07-07 20:50:11 -0700247private:
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
Romain Guyaa6c24c2011-04-28 18:40:04 -0700264 /**
265 * If set to true (by default), the layer can be reused.
266 */
Romain Guy9ace8f52011-07-07 20:50:11 -0700267 bool cacheable;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700268
269 /**
270 * When set to true, this layer must be treated as a texture
271 * layer.
272 */
Romain Guy9ace8f52011-07-07 20:50:11 -0700273 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;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700293
294 /**
295 * Optional texture coordinates transform.
296 */
297 mat4 texTransform;
Romain Guy8f0095c2011-05-02 17:24:22 -0700298
Romain Guy9ace8f52011-07-07 20:50:11 -0700299 bool firstFilter;
300 bool firstWrap;
Romain Guydda57022010-07-06 11:39:32 -0700301}; // struct Layer
302
303}; // namespace uirenderer
304}; // namespace android
305
Romain Guy5b3b3522010-10-27 18:57:51 -0700306#endif // ANDROID_HWUI_LAYER_H