blob: 71866034effd100bbe0fe76d07bc71a593aa8865 [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
Derek Sollenbergerca79cf62012-08-14 16:44:52 -040026#include <SkPaint.h>
Romain Guydda57022010-07-06 11:39:32 -070027#include <SkXfermode.h>
28
29#include "Rect.h"
Romain Guy3bbacf22013-02-06 16:51:04 -080030#include "RenderBuffer.h"
Romain Guy171c5922011-01-06 10:04:23 -080031#include "SkiaColorFilter.h"
Romain Guy9ace8f52011-07-07 20:50:11 -070032#include "Texture.h"
Romain Guyf219da52011-01-16 12:54:25 -080033#include "Vertex.h"
Romain Guydda57022010-07-06 11:39:32 -070034
35namespace android {
36namespace uirenderer {
37
Romain Guy8550c4c2010-10-08 15:49:53 -070038///////////////////////////////////////////////////////////////////////////////
39// Layers
40///////////////////////////////////////////////////////////////////////////////
Romain Guydda57022010-07-06 11:39:32 -070041
Romain Guy2bf68f02012-03-02 13:37:47 -080042// Forward declarations
43class OpenGLRenderer;
44class DisplayList;
Romain Guy96885eb2013-03-26 15:05:58 -070045class DeferredDisplayList;
46class DeferStateStruct;
Romain Guy2bf68f02012-03-02 13:37:47 -080047
Romain Guydda57022010-07-06 11:39:32 -070048/**
Romain Guyeb993562010-10-05 18:14:38 -070049 * A layer has dimensions and is backed by an OpenGL texture or FBO.
Romain Guydda57022010-07-06 11:39:32 -070050 */
51struct Layer {
Chet Haase603f6de2012-09-14 15:31:25 -070052 Layer(const uint32_t layerWidth, const uint32_t layerHeight);
Chet Haased15ebf22012-09-05 11:40:29 -070053 ~Layer();
Romain Guy8550c4c2010-10-08 15:49:53 -070054
Romain Guy2055aba2013-01-18 16:42:51 -080055 static uint32_t computeIdealWidth(uint32_t layerWidth);
56 static uint32_t computeIdealHeight(uint32_t layerHeight);
57
Romain Guy8ce00302013-01-15 18:51:42 -080058 /**
59 * Calling this method will remove (either by recycling or
60 * destroying) the associated FBO, if present, and any render
61 * buffer (stencil for instance.)
62 */
63 void removeFbo(bool flush = true);
Dave Burke56257af2012-09-25 20:30:09 -070064
Romain Guydda57022010-07-06 11:39:32 -070065 /**
Romain Guy9fc27812011-04-27 14:21:41 -070066 * Sets this layer's region to a rectangle. Computes the appropriate
67 * texture coordinates.
68 */
69 void setRegionAsRect() {
70 const android::Rect& bounds = region.getBounds();
71 regionRect.set(bounds.leftTop().x, bounds.leftTop().y,
72 bounds.rightBottom().x, bounds.rightBottom().y);
73
Romain Guy9ace8f52011-07-07 20:50:11 -070074 const float texX = 1.0f / float(texture.width);
75 const float texY = 1.0f / float(texture.height);
Romain Guy9fc27812011-04-27 14:21:41 -070076 const float height = layer.getHeight();
77 texCoords.set(
78 regionRect.left * texX, (height - regionRect.top) * texY,
79 regionRect.right * texX, (height - regionRect.bottom) * texY);
Romain Guy9ace8f52011-07-07 20:50:11 -070080
81 regionRect.translate(layer.left, layer.top);
82 }
83
Romain Guy2bf68f02012-03-02 13:37:47 -080084 void updateDeferred(OpenGLRenderer* renderer, DisplayList* displayList,
85 int left, int top, int right, int bottom) {
86 this->renderer = renderer;
87 this->displayList = displayList;
88 const Rect r(left, top, right, bottom);
89 dirtyRect.unionWith(r);
90 deferredUpdateScheduled = true;
91 }
92
Romain Guy3bbacf22013-02-06 16:51:04 -080093 inline uint32_t getWidth() const {
Romain Guy9ace8f52011-07-07 20:50:11 -070094 return texture.width;
95 }
96
Romain Guy3bbacf22013-02-06 16:51:04 -080097 inline uint32_t getHeight() const {
Romain Guy9ace8f52011-07-07 20:50:11 -070098 return texture.height;
99 }
100
Romain Guy2055aba2013-01-18 16:42:51 -0800101 /**
102 * Resize the layer and its texture if needed.
103 *
104 * @param width The new width of the layer
105 * @param height The new height of the layer
106 *
107 * @return True if the layer was resized or nothing happened, false if
108 * a failure occurred during the resizing operation
109 */
110 bool resize(const uint32_t width, const uint32_t height);
111
Romain Guy9ace8f52011-07-07 20:50:11 -0700112 void setSize(uint32_t width, uint32_t height) {
113 texture.width = width;
114 texture.height = height;
115 }
116
Chet Haased15ebf22012-09-05 11:40:29 -0700117 ANDROID_API void setPaint(SkPaint* paint);
118
Romain Guy9ace8f52011-07-07 20:50:11 -0700119 inline void setBlend(bool blend) {
120 texture.blend = blend;
121 }
122
Romain Guy3bbacf22013-02-06 16:51:04 -0800123 inline bool isBlend() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700124 return texture.blend;
125 }
126
127 inline void setAlpha(int alpha) {
128 this->alpha = alpha;
129 }
130
131 inline void setAlpha(int alpha, SkXfermode::Mode mode) {
132 this->alpha = alpha;
133 this->mode = mode;
134 }
135
Romain Guy3bbacf22013-02-06 16:51:04 -0800136 inline int getAlpha() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700137 return alpha;
138 }
139
Romain Guy3bbacf22013-02-06 16:51:04 -0800140 inline SkXfermode::Mode getMode() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700141 return mode;
142 }
143
144 inline void setEmpty(bool empty) {
145 this->empty = empty;
146 }
147
Romain Guy3bbacf22013-02-06 16:51:04 -0800148 inline bool isEmpty() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700149 return empty;
150 }
151
152 inline void setFbo(GLuint fbo) {
153 this->fbo = fbo;
154 }
155
Romain Guy3bbacf22013-02-06 16:51:04 -0800156 inline GLuint getFbo() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700157 return fbo;
158 }
159
Romain Guy3bbacf22013-02-06 16:51:04 -0800160 inline void setStencilRenderBuffer(RenderBuffer* renderBuffer) {
161 if (RenderBuffer::isStencilBuffer(renderBuffer->getFormat())) {
162 this->stencil = renderBuffer;
163 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
164 GL_RENDERBUFFER, stencil->getName());
165 } else {
166 ALOGE("The specified render buffer is not a stencil buffer");
167 }
Romain Guy8ce00302013-01-15 18:51:42 -0800168 }
169
Romain Guy3bbacf22013-02-06 16:51:04 -0800170 inline RenderBuffer* getStencilRenderBuffer() const {
Romain Guy8ce00302013-01-15 18:51:42 -0800171 return stencil;
172 }
173
Romain Guy3bbacf22013-02-06 16:51:04 -0800174 inline GLuint getTexture() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700175 return texture.id;
176 }
177
Romain Guy3bbacf22013-02-06 16:51:04 -0800178 inline GLenum getRenderTarget() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700179 return renderTarget;
180 }
181
182 inline void setRenderTarget(GLenum renderTarget) {
183 this->renderTarget = renderTarget;
184 }
185
Romain Guyd21b6e12011-11-30 20:21:23 -0800186 void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
187 texture.setWrap(wrap, bindTexture, force, renderTarget);
Romain Guy9ace8f52011-07-07 20:50:11 -0700188 }
189
Romain Guyd21b6e12011-11-30 20:21:23 -0800190 void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
191 texture.setFilter(filter, bindTexture, force, renderTarget);
Romain Guy9ace8f52011-07-07 20:50:11 -0700192 }
193
Romain Guy3bbacf22013-02-06 16:51:04 -0800194 inline bool isCacheable() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700195 return cacheable;
196 }
197
198 inline void setCacheable(bool cacheable) {
199 this->cacheable = cacheable;
200 }
201
Romain Guy3bbacf22013-02-06 16:51:04 -0800202 inline bool isDirty() const {
Romain Guy7c25aab2012-10-18 15:05:02 -0700203 return dirty;
204 }
205
206 inline void setDirty(bool dirty) {
207 this->dirty = dirty;
208 }
209
Romain Guy3bbacf22013-02-06 16:51:04 -0800210 inline bool isTextureLayer() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700211 return textureLayer;
212 }
213
214 inline void setTextureLayer(bool textureLayer) {
215 this->textureLayer = textureLayer;
216 }
217
Romain Guy3bbacf22013-02-06 16:51:04 -0800218 inline SkiaColorFilter* getColorFilter() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700219 return colorFilter;
220 }
221
Chet Haased15ebf22012-09-05 11:40:29 -0700222 ANDROID_API void setColorFilter(SkiaColorFilter* filter);
Romain Guy9ace8f52011-07-07 20:50:11 -0700223
Romain Guy3bbacf22013-02-06 16:51:04 -0800224 inline void bindTexture() const {
Romain Guyef09a212012-09-25 12:17:14 -0700225 if (texture.id) {
226 glBindTexture(renderTarget, texture.id);
227 }
Romain Guy9ace8f52011-07-07 20:50:11 -0700228 }
229
Romain Guy3bbacf22013-02-06 16:51:04 -0800230 inline void bindStencilRenderBuffer() const {
Romain Guy2055aba2013-01-18 16:42:51 -0800231 if (stencil) {
Romain Guy3bbacf22013-02-06 16:51:04 -0800232 stencil->bind();
Romain Guy2055aba2013-01-18 16:42:51 -0800233 }
234 }
235
Romain Guy9ace8f52011-07-07 20:50:11 -0700236 inline void generateTexture() {
Romain Guyef09a212012-09-25 12:17:14 -0700237 if (!texture.id) {
238 glGenTextures(1, &texture.id);
239 }
Romain Guy9ace8f52011-07-07 20:50:11 -0700240 }
241
242 inline void deleteTexture() {
Romain Guyef09a212012-09-25 12:17:14 -0700243 if (texture.id) {
244 glDeleteTextures(1, &texture.id);
245 texture.id = 0;
246 }
247 }
248
249 /**
250 * When the caller frees the texture itself, the caller
251 * must call this method to tell this layer that it lost
252 * the texture.
253 */
254 void clearTexture() {
255 texture.id = 0;
Romain Guy9ace8f52011-07-07 20:50:11 -0700256 }
257
Romain Guy09087642013-04-04 12:27:54 -0700258 inline void allocateTexture() {
Romain Guyb2e2f242012-10-17 18:18:35 -0700259#if DEBUG_LAYERS
260 ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight());
261#endif
Romain Guy2055aba2013-01-18 16:42:51 -0800262 if (texture.id) {
Romain Guy09087642013-04-04 12:27:54 -0700263 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
264 glTexImage2D(renderTarget, 0, GL_RGBA, getWidth(), getHeight(), 0,
265 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
Romain Guy2055aba2013-01-18 16:42:51 -0800266 }
267 }
268
Romain Guy9ace8f52011-07-07 20:50:11 -0700269 inline mat4& getTexTransform() {
270 return texTransform;
Romain Guy9fc27812011-04-27 14:21:41 -0700271 }
272
Romain Guy302a9df2011-08-16 13:55:02 -0700273 inline mat4& getTransform() {
274 return transform;
275 }
276
Romain Guy96885eb2013-03-26 15:05:58 -0700277 void defer();
278 void flush();
Romain Guy02b49b72013-03-29 12:37:16 -0700279 void render();
Romain Guy96885eb2013-03-26 15:05:58 -0700280
Romain Guy9fc27812011-04-27 14:21:41 -0700281 /**
Romain Guy8550c4c2010-10-08 15:49:53 -0700282 * Bounds of the layer.
Romain Guydda57022010-07-06 11:39:32 -0700283 */
284 Rect layer;
285 /**
Romain Guy8550c4c2010-10-08 15:49:53 -0700286 * Texture coordinates of the layer.
Romain Guydda57022010-07-06 11:39:32 -0700287 */
Romain Guy8550c4c2010-10-08 15:49:53 -0700288 Rect texCoords;
Romain Guyc3fedaf2013-01-29 17:26:25 -0800289 /**
290 * Clipping rectangle.
291 */
292 Rect clipRect;
Romain Guy8550c4c2010-10-08 15:49:53 -0700293
Romain Guydda57022010-07-06 11:39:32 -0700294 /**
Romain Guy5b3b3522010-10-27 18:57:51 -0700295 * Dirty region indicating what parts of the layer
296 * have been drawn.
297 */
298 Region region;
Romain Guy40667672011-03-18 14:34:03 -0700299 /**
300 * If the region is a rectangle, coordinates of the
301 * region are stored here.
302 */
303 Rect regionRect;
Romain Guy171c5922011-01-06 10:04:23 -0800304
305 /**
Romain Guyf219da52011-01-16 12:54:25 -0800306 * If the layer can be rendered as a mesh, this is non-null.
307 */
308 TextureVertex* mesh;
309 uint16_t* meshIndices;
310 GLsizei meshElementCount;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700311
Romain Guy2bf68f02012-03-02 13:37:47 -0800312 /**
313 * Used for deferred updates.
314 */
315 bool deferredUpdateScheduled;
316 OpenGLRenderer* renderer;
317 DisplayList* displayList;
318 Rect dirtyRect;
Romain Guy5bb3c732012-11-29 17:52:58 -0800319 bool debugDrawUpdate;
Chris Craik34416ea2013-04-15 16:08:28 -0700320 bool hasDrawnSinceUpdate;
Romain Guy2bf68f02012-03-02 13:37:47 -0800321
Romain Guy9ace8f52011-07-07 20:50:11 -0700322private:
323 /**
324 * Name of the FBO used to render the layer. If the name is 0
325 * this layer is not backed by an FBO, but a simple texture.
326 */
327 GLuint fbo;
328
329 /**
Romain Guy3bbacf22013-02-06 16:51:04 -0800330 * The render buffer used as the stencil buffer.
Romain Guy8ce00302013-01-15 18:51:42 -0800331 */
Romain Guy3bbacf22013-02-06 16:51:04 -0800332 RenderBuffer* stencil;
Romain Guy8ce00302013-01-15 18:51:42 -0800333
334 /**
Romain Guy9ace8f52011-07-07 20:50:11 -0700335 * Indicates whether this layer has been used already.
336 */
337 bool empty;
338
339 /**
340 * The texture backing this layer.
341 */
342 Texture texture;
343
Romain Guyaa6c24c2011-04-28 18:40:04 -0700344 /**
345 * If set to true (by default), the layer can be reused.
346 */
Romain Guy9ace8f52011-07-07 20:50:11 -0700347 bool cacheable;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700348
349 /**
350 * When set to true, this layer must be treated as a texture
351 * layer.
352 */
Romain Guy9ace8f52011-07-07 20:50:11 -0700353 bool textureLayer;
354
355 /**
Romain Guy7c25aab2012-10-18 15:05:02 -0700356 * When set to true, this layer is dirty and should be cleared
357 * before any rendering occurs.
358 */
359 bool dirty;
360
361 /**
Romain Guy9ace8f52011-07-07 20:50:11 -0700362 * Indicates the render target.
363 */
364 GLenum renderTarget;
365
366 /**
367 * Color filter used to draw this layer. Optional.
368 */
369 SkiaColorFilter* colorFilter;
370
371 /**
372 * Opacity of the layer.
373 */
374 int alpha;
375 /**
376 * Blending mode of the layer.
377 */
378 SkXfermode::Mode mode;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700379
380 /**
381 * Optional texture coordinates transform.
382 */
383 mat4 texTransform;
Romain Guy8f0095c2011-05-02 17:24:22 -0700384
Romain Guy302a9df2011-08-16 13:55:02 -0700385 /**
386 * Optional transform.
387 */
388 mat4 transform;
389
Romain Guy96885eb2013-03-26 15:05:58 -0700390 /**
391 * Used to defer display lists when the layer is updated with a
392 * display list.
393 */
394 DeferredDisplayList* deferredList;
395
Romain Guydda57022010-07-06 11:39:32 -0700396}; // struct Layer
397
398}; // namespace uirenderer
399}; // namespace android
400
Romain Guy5b3b3522010-10-27 18:57:51 -0700401#endif // ANDROID_HWUI_LAYER_H