blob: 664b2f84b6f6b4ff38e998a80b85c84467728179 [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 Guy3bbacf22013-02-06 16:51:04 -080029#include "RenderBuffer.h"
Romain Guy171c5922011-01-06 10:04:23 -080030#include "SkiaColorFilter.h"
Romain Guy9ace8f52011-07-07 20:50:11 -070031#include "Texture.h"
Romain Guyf219da52011-01-16 12:54:25 -080032#include "Vertex.h"
Romain Guydda57022010-07-06 11:39:32 -070033
34namespace android {
35namespace uirenderer {
36
Romain Guy8550c4c2010-10-08 15:49:53 -070037///////////////////////////////////////////////////////////////////////////////
38// Layers
39///////////////////////////////////////////////////////////////////////////////
Romain Guydda57022010-07-06 11:39:32 -070040
Romain Guy2bf68f02012-03-02 13:37:47 -080041// Forward declarations
42class OpenGLRenderer;
43class DisplayList;
44
Romain Guydda57022010-07-06 11:39:32 -070045/**
Romain Guyeb993562010-10-05 18:14:38 -070046 * A layer has dimensions and is backed by an OpenGL texture or FBO.
Romain Guydda57022010-07-06 11:39:32 -070047 */
48struct Layer {
Chet Haase603f6de2012-09-14 15:31:25 -070049 Layer(const uint32_t layerWidth, const uint32_t layerHeight);
Chet Haased15ebf22012-09-05 11:40:29 -070050 ~Layer();
Romain Guy8550c4c2010-10-08 15:49:53 -070051
Romain Guy2055aba2013-01-18 16:42:51 -080052 static uint32_t computeIdealWidth(uint32_t layerWidth);
53 static uint32_t computeIdealHeight(uint32_t layerHeight);
54
Romain Guy8ce00302013-01-15 18:51:42 -080055 /**
56 * Calling this method will remove (either by recycling or
57 * destroying) the associated FBO, if present, and any render
58 * buffer (stencil for instance.)
59 */
60 void removeFbo(bool flush = true);
Dave Burke56257af2012-09-25 20:30:09 -070061
Romain Guydda57022010-07-06 11:39:32 -070062 /**
Romain Guy9fc27812011-04-27 14:21:41 -070063 * Sets this layer's region to a rectangle. Computes the appropriate
64 * texture coordinates.
65 */
66 void setRegionAsRect() {
67 const android::Rect& bounds = region.getBounds();
68 regionRect.set(bounds.leftTop().x, bounds.leftTop().y,
69 bounds.rightBottom().x, bounds.rightBottom().y);
70
Romain Guy9ace8f52011-07-07 20:50:11 -070071 const float texX = 1.0f / float(texture.width);
72 const float texY = 1.0f / float(texture.height);
Romain Guy9fc27812011-04-27 14:21:41 -070073 const float height = layer.getHeight();
74 texCoords.set(
75 regionRect.left * texX, (height - regionRect.top) * texY,
76 regionRect.right * texX, (height - regionRect.bottom) * texY);
Romain Guy9ace8f52011-07-07 20:50:11 -070077
78 regionRect.translate(layer.left, layer.top);
79 }
80
Romain Guy2bf68f02012-03-02 13:37:47 -080081 void updateDeferred(OpenGLRenderer* renderer, DisplayList* displayList,
82 int left, int top, int right, int bottom) {
83 this->renderer = renderer;
84 this->displayList = displayList;
85 const Rect r(left, top, right, bottom);
86 dirtyRect.unionWith(r);
87 deferredUpdateScheduled = true;
88 }
89
Romain Guy3bbacf22013-02-06 16:51:04 -080090 inline uint32_t getWidth() const {
Romain Guy9ace8f52011-07-07 20:50:11 -070091 return texture.width;
92 }
93
Romain Guy3bbacf22013-02-06 16:51:04 -080094 inline uint32_t getHeight() const {
Romain Guy9ace8f52011-07-07 20:50:11 -070095 return texture.height;
96 }
97
Romain Guy2055aba2013-01-18 16:42:51 -080098 /**
99 * Resize the layer and its texture if needed.
100 *
101 * @param width The new width of the layer
102 * @param height The new height of the layer
103 *
104 * @return True if the layer was resized or nothing happened, false if
105 * a failure occurred during the resizing operation
106 */
107 bool resize(const uint32_t width, const uint32_t height);
108
Romain Guy9ace8f52011-07-07 20:50:11 -0700109 void setSize(uint32_t width, uint32_t height) {
110 texture.width = width;
111 texture.height = height;
112 }
113
Chet Haased15ebf22012-09-05 11:40:29 -0700114 ANDROID_API void setPaint(SkPaint* paint);
115
Romain Guy9ace8f52011-07-07 20:50:11 -0700116 inline void setBlend(bool blend) {
117 texture.blend = blend;
118 }
119
Romain Guy3bbacf22013-02-06 16:51:04 -0800120 inline bool isBlend() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700121 return texture.blend;
122 }
123
124 inline void setAlpha(int alpha) {
125 this->alpha = alpha;
126 }
127
128 inline void setAlpha(int alpha, SkXfermode::Mode mode) {
129 this->alpha = alpha;
130 this->mode = mode;
131 }
132
Romain Guy3bbacf22013-02-06 16:51:04 -0800133 inline int getAlpha() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700134 return alpha;
135 }
136
Romain Guy3bbacf22013-02-06 16:51:04 -0800137 inline SkXfermode::Mode getMode() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700138 return mode;
139 }
140
141 inline void setEmpty(bool empty) {
142 this->empty = empty;
143 }
144
Romain Guy3bbacf22013-02-06 16:51:04 -0800145 inline bool isEmpty() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700146 return empty;
147 }
148
149 inline void setFbo(GLuint fbo) {
150 this->fbo = fbo;
151 }
152
Romain Guy3bbacf22013-02-06 16:51:04 -0800153 inline GLuint getFbo() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700154 return fbo;
155 }
156
Romain Guy3bbacf22013-02-06 16:51:04 -0800157 inline void setStencilRenderBuffer(RenderBuffer* renderBuffer) {
158 if (RenderBuffer::isStencilBuffer(renderBuffer->getFormat())) {
159 this->stencil = renderBuffer;
160 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
161 GL_RENDERBUFFER, stencil->getName());
162 } else {
163 ALOGE("The specified render buffer is not a stencil buffer");
164 }
Romain Guy8ce00302013-01-15 18:51:42 -0800165 }
166
Romain Guy3bbacf22013-02-06 16:51:04 -0800167 inline RenderBuffer* getStencilRenderBuffer() const {
Romain Guy8ce00302013-01-15 18:51:42 -0800168 return stencil;
169 }
170
Romain Guy3bbacf22013-02-06 16:51:04 -0800171 inline GLuint getTexture() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700172 return texture.id;
173 }
174
Romain Guy3bbacf22013-02-06 16:51:04 -0800175 inline GLenum getRenderTarget() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700176 return renderTarget;
177 }
178
179 inline void setRenderTarget(GLenum renderTarget) {
180 this->renderTarget = renderTarget;
181 }
182
Romain Guyd21b6e12011-11-30 20:21:23 -0800183 void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
184 texture.setWrap(wrap, bindTexture, force, renderTarget);
Romain Guy9ace8f52011-07-07 20:50:11 -0700185 }
186
Romain Guyd21b6e12011-11-30 20:21:23 -0800187 void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
188 texture.setFilter(filter, bindTexture, force, renderTarget);
Romain Guy9ace8f52011-07-07 20:50:11 -0700189 }
190
Romain Guy3bbacf22013-02-06 16:51:04 -0800191 inline bool isCacheable() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700192 return cacheable;
193 }
194
195 inline void setCacheable(bool cacheable) {
196 this->cacheable = cacheable;
197 }
198
Romain Guy3bbacf22013-02-06 16:51:04 -0800199 inline bool isDirty() const {
Romain Guy7c25aab2012-10-18 15:05:02 -0700200 return dirty;
201 }
202
203 inline void setDirty(bool dirty) {
204 this->dirty = dirty;
205 }
206
Romain Guy3bbacf22013-02-06 16:51:04 -0800207 inline bool isTextureLayer() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700208 return textureLayer;
209 }
210
211 inline void setTextureLayer(bool textureLayer) {
212 this->textureLayer = textureLayer;
213 }
214
Romain Guy3bbacf22013-02-06 16:51:04 -0800215 inline SkiaColorFilter* getColorFilter() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700216 return colorFilter;
217 }
218
Chet Haased15ebf22012-09-05 11:40:29 -0700219 ANDROID_API void setColorFilter(SkiaColorFilter* filter);
Romain Guy9ace8f52011-07-07 20:50:11 -0700220
Romain Guy3bbacf22013-02-06 16:51:04 -0800221 inline void bindTexture() const {
Romain Guyef09a212012-09-25 12:17:14 -0700222 if (texture.id) {
223 glBindTexture(renderTarget, texture.id);
224 }
Romain Guy9ace8f52011-07-07 20:50:11 -0700225 }
226
Romain Guy3bbacf22013-02-06 16:51:04 -0800227 inline void bindStencilRenderBuffer() const {
Romain Guy2055aba2013-01-18 16:42:51 -0800228 if (stencil) {
Romain Guy3bbacf22013-02-06 16:51:04 -0800229 stencil->bind();
Romain Guy2055aba2013-01-18 16:42:51 -0800230 }
231 }
232
Romain Guy9ace8f52011-07-07 20:50:11 -0700233 inline void generateTexture() {
Romain Guyef09a212012-09-25 12:17:14 -0700234 if (!texture.id) {
235 glGenTextures(1, &texture.id);
236 }
Romain Guy9ace8f52011-07-07 20:50:11 -0700237 }
238
239 inline void deleteTexture() {
Romain Guyef09a212012-09-25 12:17:14 -0700240 if (texture.id) {
241 glDeleteTextures(1, &texture.id);
242 texture.id = 0;
243 }
244 }
245
246 /**
247 * When the caller frees the texture itself, the caller
248 * must call this method to tell this layer that it lost
249 * the texture.
250 */
251 void clearTexture() {
252 texture.id = 0;
Romain Guy9ace8f52011-07-07 20:50:11 -0700253 }
254
255 inline void allocateTexture(GLenum format, GLenum storage) {
Romain Guyb2e2f242012-10-17 18:18:35 -0700256#if DEBUG_LAYERS
257 ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight());
258#endif
Romain Guy2055aba2013-01-18 16:42:51 -0800259 if (texture.id) {
260 glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0,
261 format, storage, NULL);
262 }
263 }
264
Romain Guy9ace8f52011-07-07 20:50:11 -0700265 inline mat4& getTexTransform() {
266 return texTransform;
Romain Guy9fc27812011-04-27 14:21:41 -0700267 }
268
Romain Guy302a9df2011-08-16 13:55:02 -0700269 inline mat4& getTransform() {
270 return transform;
271 }
272
Romain Guy9fc27812011-04-27 14:21:41 -0700273 /**
Romain Guy8550c4c2010-10-08 15:49:53 -0700274 * Bounds of the layer.
Romain Guydda57022010-07-06 11:39:32 -0700275 */
276 Rect layer;
277 /**
Romain Guy8550c4c2010-10-08 15:49:53 -0700278 * Texture coordinates of the layer.
Romain Guydda57022010-07-06 11:39:32 -0700279 */
Romain Guy8550c4c2010-10-08 15:49:53 -0700280 Rect texCoords;
Romain Guyc3fedaf2013-01-29 17:26:25 -0800281 /**
282 * Clipping rectangle.
283 */
284 Rect clipRect;
Romain Guy8550c4c2010-10-08 15:49:53 -0700285
Romain Guydda57022010-07-06 11:39:32 -0700286 /**
Romain Guy5b3b3522010-10-27 18:57:51 -0700287 * Dirty region indicating what parts of the layer
288 * have been drawn.
289 */
290 Region region;
Romain Guy40667672011-03-18 14:34:03 -0700291 /**
292 * If the region is a rectangle, coordinates of the
293 * region are stored here.
294 */
295 Rect regionRect;
Romain Guy171c5922011-01-06 10:04:23 -0800296
297 /**
Romain Guyf219da52011-01-16 12:54:25 -0800298 * If the layer can be rendered as a mesh, this is non-null.
299 */
300 TextureVertex* mesh;
301 uint16_t* meshIndices;
302 GLsizei meshElementCount;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700303
Romain Guy2bf68f02012-03-02 13:37:47 -0800304 /**
305 * Used for deferred updates.
306 */
307 bool deferredUpdateScheduled;
308 OpenGLRenderer* renderer;
309 DisplayList* displayList;
310 Rect dirtyRect;
Romain Guy5bb3c732012-11-29 17:52:58 -0800311 bool debugDrawUpdate;
Romain Guy2bf68f02012-03-02 13:37:47 -0800312
Romain Guy9ace8f52011-07-07 20:50:11 -0700313private:
314 /**
315 * Name of the FBO used to render the layer. If the name is 0
316 * this layer is not backed by an FBO, but a simple texture.
317 */
318 GLuint fbo;
319
320 /**
Romain Guy3bbacf22013-02-06 16:51:04 -0800321 * The render buffer used as the stencil buffer.
Romain Guy8ce00302013-01-15 18:51:42 -0800322 */
Romain Guy3bbacf22013-02-06 16:51:04 -0800323 RenderBuffer* stencil;
Romain Guy8ce00302013-01-15 18:51:42 -0800324
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