blob: e8a85fdf3dde66f57c754fec9f865994477e9487 [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
Romain Guy2bf68f02012-03-02 13:37:47 -080040// Forward declarations
41class OpenGLRenderer;
42class DisplayList;
43
Romain Guydda57022010-07-06 11:39:32 -070044/**
Romain Guyeb993562010-10-05 18:14:38 -070045 * A layer has dimensions and is backed by an OpenGL texture or FBO.
Romain Guydda57022010-07-06 11:39:32 -070046 */
47struct Layer {
Chet Haase603f6de2012-09-14 15:31:25 -070048 Layer(const uint32_t layerWidth, const uint32_t layerHeight);
Chet Haased15ebf22012-09-05 11:40:29 -070049 ~Layer();
Romain Guy8550c4c2010-10-08 15:49:53 -070050
Romain Guy2055aba2013-01-18 16:42:51 -080051 static uint32_t computeIdealWidth(uint32_t layerWidth);
52 static uint32_t computeIdealHeight(uint32_t layerHeight);
53
Romain Guy8ce00302013-01-15 18:51:42 -080054 /**
55 * Calling this method will remove (either by recycling or
56 * destroying) the associated FBO, if present, and any render
57 * buffer (stencil for instance.)
58 */
59 void removeFbo(bool flush = true);
Dave Burke56257af2012-09-25 20:30:09 -070060
Romain Guydda57022010-07-06 11:39:32 -070061 /**
Romain Guy9fc27812011-04-27 14:21:41 -070062 * 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
Romain Guy9ace8f52011-07-07 20:50:11 -070070 const float texX = 1.0f / float(texture.width);
71 const float texY = 1.0f / float(texture.height);
Romain Guy9fc27812011-04-27 14:21:41 -070072 const float height = layer.getHeight();
73 texCoords.set(
74 regionRect.left * texX, (height - regionRect.top) * texY,
75 regionRect.right * texX, (height - regionRect.bottom) * texY);
Romain Guy9ace8f52011-07-07 20:50:11 -070076
77 regionRect.translate(layer.left, layer.top);
78 }
79
Romain Guy2bf68f02012-03-02 13:37:47 -080080 void updateDeferred(OpenGLRenderer* renderer, DisplayList* displayList,
81 int left, int top, int right, int bottom) {
82 this->renderer = renderer;
83 this->displayList = displayList;
84 const Rect r(left, top, right, bottom);
85 dirtyRect.unionWith(r);
86 deferredUpdateScheduled = true;
87 }
88
Romain Guy9ace8f52011-07-07 20:50:11 -070089 inline uint32_t getWidth() {
90 return texture.width;
91 }
92
93 inline uint32_t getHeight() {
94 return texture.height;
95 }
96
Romain Guy2055aba2013-01-18 16:42:51 -080097 /**
98 * Resize the layer and its texture if needed.
99 *
100 * @param width The new width of the layer
101 * @param height The new height of the layer
102 *
103 * @return True if the layer was resized or nothing happened, false if
104 * a failure occurred during the resizing operation
105 */
106 bool resize(const uint32_t width, const uint32_t height);
107
Romain Guy9ace8f52011-07-07 20:50:11 -0700108 void setSize(uint32_t width, uint32_t height) {
109 texture.width = width;
110 texture.height = height;
111 }
112
Chet Haased15ebf22012-09-05 11:40:29 -0700113 ANDROID_API void setPaint(SkPaint* paint);
114
Romain Guy9ace8f52011-07-07 20:50:11 -0700115 inline void setBlend(bool blend) {
116 texture.blend = blend;
117 }
118
119 inline bool isBlend() {
120 return texture.blend;
121 }
122
123 inline void setAlpha(int alpha) {
124 this->alpha = alpha;
125 }
126
127 inline void setAlpha(int alpha, SkXfermode::Mode mode) {
128 this->alpha = alpha;
129 this->mode = mode;
130 }
131
132 inline int getAlpha() {
133 return alpha;
134 }
135
136 inline SkXfermode::Mode getMode() {
137 return mode;
138 }
139
140 inline void setEmpty(bool empty) {
141 this->empty = empty;
142 }
143
144 inline bool isEmpty() {
145 return empty;
146 }
147
148 inline void setFbo(GLuint fbo) {
149 this->fbo = fbo;
150 }
151
152 inline GLuint getFbo() {
153 return fbo;
154 }
155
Romain Guy8ce00302013-01-15 18:51:42 -0800156 inline void setStencilRenderBuffer(GLuint renderBuffer) {
157 this->stencil = renderBuffer;
158 }
159
160 inline GLuint getStencilRenderBuffer() {
161 return stencil;
162 }
163
Romain Guy9ace8f52011-07-07 20:50:11 -0700164 inline GLuint getTexture() {
165 return texture.id;
166 }
167
168 inline GLenum getRenderTarget() {
169 return renderTarget;
170 }
171
172 inline void setRenderTarget(GLenum renderTarget) {
173 this->renderTarget = renderTarget;
174 }
175
Romain Guyd21b6e12011-11-30 20:21:23 -0800176 void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
177 texture.setWrap(wrap, bindTexture, force, renderTarget);
Romain Guy9ace8f52011-07-07 20:50:11 -0700178 }
179
Romain Guyd21b6e12011-11-30 20:21:23 -0800180 void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
181 texture.setFilter(filter, bindTexture, force, renderTarget);
Romain Guy9ace8f52011-07-07 20:50:11 -0700182 }
183
184 inline bool isCacheable() {
185 return cacheable;
186 }
187
188 inline void setCacheable(bool cacheable) {
189 this->cacheable = cacheable;
190 }
191
Romain Guy7c25aab2012-10-18 15:05:02 -0700192 inline bool isDirty() {
193 return dirty;
194 }
195
196 inline void setDirty(bool dirty) {
197 this->dirty = dirty;
198 }
199
Romain Guy9ace8f52011-07-07 20:50:11 -0700200 inline bool isTextureLayer() {
201 return textureLayer;
202 }
203
204 inline void setTextureLayer(bool textureLayer) {
205 this->textureLayer = textureLayer;
206 }
207
208 inline SkiaColorFilter* getColorFilter() {
209 return colorFilter;
210 }
211
Chet Haased15ebf22012-09-05 11:40:29 -0700212 ANDROID_API void setColorFilter(SkiaColorFilter* filter);
Romain Guy9ace8f52011-07-07 20:50:11 -0700213
214 inline void bindTexture() {
Romain Guyef09a212012-09-25 12:17:14 -0700215 if (texture.id) {
216 glBindTexture(renderTarget, texture.id);
217 }
Romain Guy9ace8f52011-07-07 20:50:11 -0700218 }
219
Romain Guy2055aba2013-01-18 16:42:51 -0800220 inline void bindStencilRenderBuffer() {
221 if (stencil) {
222 glBindRenderbuffer(GL_RENDERBUFFER, stencil);
223 }
224 }
225
Romain Guy9ace8f52011-07-07 20:50:11 -0700226 inline void generateTexture() {
Romain Guyef09a212012-09-25 12:17:14 -0700227 if (!texture.id) {
228 glGenTextures(1, &texture.id);
229 }
Romain Guy9ace8f52011-07-07 20:50:11 -0700230 }
231
232 inline void deleteTexture() {
Romain Guyef09a212012-09-25 12:17:14 -0700233 if (texture.id) {
234 glDeleteTextures(1, &texture.id);
235 texture.id = 0;
236 }
237 }
238
239 /**
240 * When the caller frees the texture itself, the caller
241 * must call this method to tell this layer that it lost
242 * the texture.
243 */
244 void clearTexture() {
245 texture.id = 0;
Romain Guy9ace8f52011-07-07 20:50:11 -0700246 }
247
248 inline void allocateTexture(GLenum format, GLenum storage) {
Romain Guyb2e2f242012-10-17 18:18:35 -0700249#if DEBUG_LAYERS
250 ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight());
251#endif
Romain Guy2055aba2013-01-18 16:42:51 -0800252 if (texture.id) {
253 glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0,
254 format, storage, NULL);
255 }
256 }
257
258 inline void allocateStencilRenderBuffer() {
259 if (stencil) {
260 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, getWidth(), getHeight());
261 }
Romain Guy9ace8f52011-07-07 20:50:11 -0700262 }
263
264 inline mat4& getTexTransform() {
265 return texTransform;
Romain Guy9fc27812011-04-27 14:21:41 -0700266 }
267
Romain Guy302a9df2011-08-16 13:55:02 -0700268 inline mat4& getTransform() {
269 return transform;
270 }
271
Romain Guy9fc27812011-04-27 14:21:41 -0700272 /**
Romain Guy8550c4c2010-10-08 15:49:53 -0700273 * Bounds of the layer.
Romain Guydda57022010-07-06 11:39:32 -0700274 */
275 Rect layer;
276 /**
Romain Guy8550c4c2010-10-08 15:49:53 -0700277 * Texture coordinates of the layer.
Romain Guydda57022010-07-06 11:39:32 -0700278 */
Romain Guy8550c4c2010-10-08 15:49:53 -0700279 Rect texCoords;
Romain Guyc3fedaf2013-01-29 17:26:25 -0800280 /**
281 * Clipping rectangle.
282 */
283 Rect clipRect;
Romain Guy8550c4c2010-10-08 15:49:53 -0700284
Romain Guydda57022010-07-06 11:39:32 -0700285 /**
Romain Guy5b3b3522010-10-27 18:57:51 -0700286 * Dirty region indicating what parts of the layer
287 * have been drawn.
288 */
289 Region region;
Romain Guy40667672011-03-18 14:34:03 -0700290 /**
291 * If the region is a rectangle, coordinates of the
292 * region are stored here.
293 */
294 Rect regionRect;
Romain Guy171c5922011-01-06 10:04:23 -0800295
296 /**
Romain Guyf219da52011-01-16 12:54:25 -0800297 * If the layer can be rendered as a mesh, this is non-null.
298 */
299 TextureVertex* mesh;
300 uint16_t* meshIndices;
301 GLsizei meshElementCount;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700302
Romain Guy2bf68f02012-03-02 13:37:47 -0800303 /**
304 * Used for deferred updates.
305 */
306 bool deferredUpdateScheduled;
307 OpenGLRenderer* renderer;
308 DisplayList* displayList;
309 Rect dirtyRect;
Romain Guy5bb3c732012-11-29 17:52:58 -0800310 bool debugDrawUpdate;
Romain Guy2bf68f02012-03-02 13:37:47 -0800311
Romain Guy9ace8f52011-07-07 20:50:11 -0700312private:
313 /**
314 * Name of the FBO used to render the layer. If the name is 0
315 * this layer is not backed by an FBO, but a simple texture.
316 */
317 GLuint fbo;
318
319 /**
Romain Guy8ce00302013-01-15 18:51:42 -0800320 * Name of the render buffer used as the stencil buffer. If the
321 * name is 0, this layer does not have a stencil buffer.
322 */
323 GLuint stencil;
324
325 /**
Romain Guy9ace8f52011-07-07 20:50:11 -0700326 * Indicates whether this layer has been used already.
327 */
328 bool empty;
329
330 /**
331 * The texture backing this layer.
332 */
333 Texture texture;
334
Romain Guyaa6c24c2011-04-28 18:40:04 -0700335 /**
336 * If set to true (by default), the layer can be reused.
337 */
Romain Guy9ace8f52011-07-07 20:50:11 -0700338 bool cacheable;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700339
340 /**
341 * When set to true, this layer must be treated as a texture
342 * layer.
343 */
Romain Guy9ace8f52011-07-07 20:50:11 -0700344 bool textureLayer;
345
346 /**
Romain Guy7c25aab2012-10-18 15:05:02 -0700347 * When set to true, this layer is dirty and should be cleared
348 * before any rendering occurs.
349 */
350 bool dirty;
351
352 /**
Romain Guy9ace8f52011-07-07 20:50:11 -0700353 * Indicates the render target.
354 */
355 GLenum renderTarget;
356
357 /**
358 * Color filter used to draw this layer. Optional.
359 */
360 SkiaColorFilter* colorFilter;
361
362 /**
363 * Opacity of the layer.
364 */
365 int alpha;
366 /**
367 * Blending mode of the layer.
368 */
369 SkXfermode::Mode mode;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700370
371 /**
372 * Optional texture coordinates transform.
373 */
374 mat4 texTransform;
Romain Guy8f0095c2011-05-02 17:24:22 -0700375
Romain Guy302a9df2011-08-16 13:55:02 -0700376 /**
377 * Optional transform.
378 */
379 mat4 transform;
380
Romain Guydda57022010-07-06 11:39:32 -0700381}; // struct Layer
382
383}; // namespace uirenderer
384}; // namespace android
385
Romain Guy5b3b3522010-10-27 18:57:51 -0700386#endif // ANDROID_HWUI_LAYER_H