blob: 27e0cf169e437bc91f33856a8de2829c2f262caf [file] [log] [blame]
Romain Guydda570202010-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 Guydda570202010-07-06 11:39:32 -070019
Romain Guyf7f93552010-07-08 19:17:03 -070020#include <sys/types.h>
21
Romain Guydda570202010-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 Guydda570202010-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 Guydda570202010-07-06 11:39:32 -070034
35namespace android {
36namespace uirenderer {
37
Romain Guy8550c4c2010-10-08 15:49:53 -070038///////////////////////////////////////////////////////////////////////////////
39// Layers
40///////////////////////////////////////////////////////////////////////////////
Romain Guydda570202010-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 Guydda570202010-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 Guydda570202010-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 Guydda570202010-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
258 inline void allocateTexture(GLenum format, GLenum storage) {
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) {
263 glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0,
264 format, storage, NULL);
265 }
266 }
267
Romain Guy9ace8f52011-07-07 20:50:11 -0700268 inline mat4& getTexTransform() {
269 return texTransform;
Romain Guy9fc27812011-04-27 14:21:41 -0700270 }
271
Romain Guy302a9df2011-08-16 13:55:02 -0700272 inline mat4& getTransform() {
273 return transform;
274 }
275
Romain Guy96885eb2013-03-26 15:05:58 -0700276 void defer();
277 void flush();
Romain Guy02b49b72013-03-29 12:37:16 -0700278 void render();
Romain Guy96885eb2013-03-26 15:05:58 -0700279
Romain Guy9fc27812011-04-27 14:21:41 -0700280 /**
Romain Guy8550c4c2010-10-08 15:49:53 -0700281 * Bounds of the layer.
Romain Guydda570202010-07-06 11:39:32 -0700282 */
283 Rect layer;
284 /**
Romain Guy8550c4c2010-10-08 15:49:53 -0700285 * Texture coordinates of the layer.
Romain Guydda570202010-07-06 11:39:32 -0700286 */
Romain Guy8550c4c2010-10-08 15:49:53 -0700287 Rect texCoords;
Romain Guyc3fedaf2013-01-29 17:26:25 -0800288 /**
289 * Clipping rectangle.
290 */
291 Rect clipRect;
Romain Guy8550c4c2010-10-08 15:49:53 -0700292
Romain Guydda570202010-07-06 11:39:32 -0700293 /**
Romain Guy5b3b3522010-10-27 18:57:51 -0700294 * Dirty region indicating what parts of the layer
295 * have been drawn.
296 */
297 Region region;
Romain Guy40667672011-03-18 14:34:03 -0700298 /**
299 * If the region is a rectangle, coordinates of the
300 * region are stored here.
301 */
302 Rect regionRect;
Romain Guy171c5922011-01-06 10:04:23 -0800303
304 /**
Romain Guyf219da52011-01-16 12:54:25 -0800305 * If the layer can be rendered as a mesh, this is non-null.
306 */
307 TextureVertex* mesh;
308 uint16_t* meshIndices;
309 GLsizei meshElementCount;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700310
Romain Guy2bf68f02012-03-02 13:37:47 -0800311 /**
312 * Used for deferred updates.
313 */
314 bool deferredUpdateScheduled;
315 OpenGLRenderer* renderer;
316 DisplayList* displayList;
317 Rect dirtyRect;
Romain Guy5bb3c732012-11-29 17:52:58 -0800318 bool debugDrawUpdate;
Romain Guy2bf68f02012-03-02 13:37:47 -0800319
Romain Guy9ace8f52011-07-07 20:50:11 -0700320private:
321 /**
322 * Name of the FBO used to render the layer. If the name is 0
323 * this layer is not backed by an FBO, but a simple texture.
324 */
325 GLuint fbo;
326
327 /**
Romain Guy3bbacf22013-02-06 16:51:04 -0800328 * The render buffer used as the stencil buffer.
Romain Guy8ce00302013-01-15 18:51:42 -0800329 */
Romain Guy3bbacf22013-02-06 16:51:04 -0800330 RenderBuffer* stencil;
Romain Guy8ce00302013-01-15 18:51:42 -0800331
332 /**
Romain Guy9ace8f52011-07-07 20:50:11 -0700333 * Indicates whether this layer has been used already.
334 */
335 bool empty;
336
337 /**
338 * The texture backing this layer.
339 */
340 Texture texture;
341
Romain Guyaa6c24c2011-04-28 18:40:04 -0700342 /**
343 * If set to true (by default), the layer can be reused.
344 */
Romain Guy9ace8f52011-07-07 20:50:11 -0700345 bool cacheable;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700346
347 /**
348 * When set to true, this layer must be treated as a texture
349 * layer.
350 */
Romain Guy9ace8f52011-07-07 20:50:11 -0700351 bool textureLayer;
352
353 /**
Romain Guy7c25aab2012-10-18 15:05:02 -0700354 * When set to true, this layer is dirty and should be cleared
355 * before any rendering occurs.
356 */
357 bool dirty;
358
359 /**
Romain Guy9ace8f52011-07-07 20:50:11 -0700360 * Indicates the render target.
361 */
362 GLenum renderTarget;
363
364 /**
365 * Color filter used to draw this layer. Optional.
366 */
367 SkiaColorFilter* colorFilter;
368
369 /**
370 * Opacity of the layer.
371 */
372 int alpha;
373 /**
374 * Blending mode of the layer.
375 */
376 SkXfermode::Mode mode;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700377
378 /**
379 * Optional texture coordinates transform.
380 */
381 mat4 texTransform;
Romain Guy8f0095c2011-05-02 17:24:22 -0700382
Romain Guy302a9df2011-08-16 13:55:02 -0700383 /**
384 * Optional transform.
385 */
386 mat4 transform;
387
Romain Guy96885eb2013-03-26 15:05:58 -0700388 /**
389 * Used to defer display lists when the layer is updated with a
390 * display list.
391 */
392 DeferredDisplayList* deferredList;
393
Romain Guydda570202010-07-06 11:39:32 -0700394}; // struct Layer
395
396}; // namespace uirenderer
397}; // namespace android
398
Romain Guy5b3b3522010-10-27 18:57:51 -0700399#endif // ANDROID_HWUI_LAYER_H