blob: ccf1da5539aaaf52898af58412b9da0f6915a89f [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;
45
Romain Guydda570202010-07-06 11:39:32 -070046/**
Romain Guyeb993562010-10-05 18:14:38 -070047 * A layer has dimensions and is backed by an OpenGL texture or FBO.
Romain Guydda570202010-07-06 11:39:32 -070048 */
49struct Layer {
Chet Haase603f6de2012-09-14 15:31:25 -070050 Layer(const uint32_t layerWidth, const uint32_t layerHeight);
Chet Haased15ebf22012-09-05 11:40:29 -070051 ~Layer();
Romain Guy8550c4c2010-10-08 15:49:53 -070052
Romain Guy2055aba2013-01-18 16:42:51 -080053 static uint32_t computeIdealWidth(uint32_t layerWidth);
54 static uint32_t computeIdealHeight(uint32_t layerHeight);
55
Romain Guy8ce00302013-01-15 18:51:42 -080056 /**
57 * Calling this method will remove (either by recycling or
58 * destroying) the associated FBO, if present, and any render
59 * buffer (stencil for instance.)
60 */
61 void removeFbo(bool flush = true);
Dave Burke56257af2012-09-25 20:30:09 -070062
Romain Guydda570202010-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
Romain Guy2bf68f02012-03-02 13:37:47 -080082 void updateDeferred(OpenGLRenderer* renderer, DisplayList* displayList,
83 int left, int top, int right, int bottom) {
84 this->renderer = renderer;
85 this->displayList = displayList;
86 const Rect r(left, top, right, bottom);
87 dirtyRect.unionWith(r);
88 deferredUpdateScheduled = true;
89 }
90
Romain Guy3bbacf22013-02-06 16:51:04 -080091 inline uint32_t getWidth() const {
Romain Guy9ace8f52011-07-07 20:50:11 -070092 return texture.width;
93 }
94
Romain Guy3bbacf22013-02-06 16:51:04 -080095 inline uint32_t getHeight() const {
Romain Guy9ace8f52011-07-07 20:50:11 -070096 return texture.height;
97 }
98
Romain Guy2055aba2013-01-18 16:42:51 -080099 /**
100 * Resize the layer and its texture if needed.
101 *
102 * @param width The new width of the layer
103 * @param height The new height of the layer
104 *
105 * @return True if the layer was resized or nothing happened, false if
106 * a failure occurred during the resizing operation
107 */
108 bool resize(const uint32_t width, const uint32_t height);
109
Romain Guy9ace8f52011-07-07 20:50:11 -0700110 void setSize(uint32_t width, uint32_t height) {
111 texture.width = width;
112 texture.height = height;
113 }
114
Chet Haased15ebf22012-09-05 11:40:29 -0700115 ANDROID_API void setPaint(SkPaint* paint);
116
Romain Guy9ace8f52011-07-07 20:50:11 -0700117 inline void setBlend(bool blend) {
118 texture.blend = blend;
119 }
120
Romain Guy3bbacf22013-02-06 16:51:04 -0800121 inline bool isBlend() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700122 return texture.blend;
123 }
124
125 inline void setAlpha(int alpha) {
126 this->alpha = alpha;
127 }
128
129 inline void setAlpha(int alpha, SkXfermode::Mode mode) {
130 this->alpha = alpha;
131 this->mode = mode;
132 }
133
Romain Guy3bbacf22013-02-06 16:51:04 -0800134 inline int getAlpha() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700135 return alpha;
136 }
137
Romain Guy3bbacf22013-02-06 16:51:04 -0800138 inline SkXfermode::Mode getMode() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700139 return mode;
140 }
141
142 inline void setEmpty(bool empty) {
143 this->empty = empty;
144 }
145
Romain Guy3bbacf22013-02-06 16:51:04 -0800146 inline bool isEmpty() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700147 return empty;
148 }
149
150 inline void setFbo(GLuint fbo) {
151 this->fbo = fbo;
152 }
153
Romain Guy3bbacf22013-02-06 16:51:04 -0800154 inline GLuint getFbo() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700155 return fbo;
156 }
157
Romain Guy3bbacf22013-02-06 16:51:04 -0800158 inline void setStencilRenderBuffer(RenderBuffer* renderBuffer) {
159 if (RenderBuffer::isStencilBuffer(renderBuffer->getFormat())) {
160 this->stencil = renderBuffer;
161 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
162 GL_RENDERBUFFER, stencil->getName());
163 } else {
164 ALOGE("The specified render buffer is not a stencil buffer");
165 }
Romain Guy8ce00302013-01-15 18:51:42 -0800166 }
167
Romain Guy3bbacf22013-02-06 16:51:04 -0800168 inline RenderBuffer* getStencilRenderBuffer() const {
Romain Guy8ce00302013-01-15 18:51:42 -0800169 return stencil;
170 }
171
Romain Guy3bbacf22013-02-06 16:51:04 -0800172 inline GLuint getTexture() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700173 return texture.id;
174 }
175
Romain Guy3bbacf22013-02-06 16:51:04 -0800176 inline GLenum getRenderTarget() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700177 return renderTarget;
178 }
179
180 inline void setRenderTarget(GLenum renderTarget) {
181 this->renderTarget = renderTarget;
182 }
183
Romain Guyd21b6e12011-11-30 20:21:23 -0800184 void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
185 texture.setWrap(wrap, bindTexture, force, renderTarget);
Romain Guy9ace8f52011-07-07 20:50:11 -0700186 }
187
Romain Guyd21b6e12011-11-30 20:21:23 -0800188 void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
189 texture.setFilter(filter, bindTexture, force, renderTarget);
Romain Guy9ace8f52011-07-07 20:50:11 -0700190 }
191
Romain Guy3bbacf22013-02-06 16:51:04 -0800192 inline bool isCacheable() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700193 return cacheable;
194 }
195
196 inline void setCacheable(bool cacheable) {
197 this->cacheable = cacheable;
198 }
199
Romain Guy3bbacf22013-02-06 16:51:04 -0800200 inline bool isDirty() const {
Romain Guy7c25aab2012-10-18 15:05:02 -0700201 return dirty;
202 }
203
204 inline void setDirty(bool dirty) {
205 this->dirty = dirty;
206 }
207
Romain Guy3bbacf22013-02-06 16:51:04 -0800208 inline bool isTextureLayer() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700209 return textureLayer;
210 }
211
212 inline void setTextureLayer(bool textureLayer) {
213 this->textureLayer = textureLayer;
214 }
215
Romain Guy3bbacf22013-02-06 16:51:04 -0800216 inline SkiaColorFilter* getColorFilter() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700217 return colorFilter;
218 }
219
Chet Haased15ebf22012-09-05 11:40:29 -0700220 ANDROID_API void setColorFilter(SkiaColorFilter* filter);
Romain Guy9ace8f52011-07-07 20:50:11 -0700221
Romain Guy3bbacf22013-02-06 16:51:04 -0800222 inline void bindTexture() const {
Romain Guyef09a212012-09-25 12:17:14 -0700223 if (texture.id) {
224 glBindTexture(renderTarget, texture.id);
225 }
Romain Guy9ace8f52011-07-07 20:50:11 -0700226 }
227
Romain Guy3bbacf22013-02-06 16:51:04 -0800228 inline void bindStencilRenderBuffer() const {
Romain Guy2055aba2013-01-18 16:42:51 -0800229 if (stencil) {
Romain Guy3bbacf22013-02-06 16:51:04 -0800230 stencil->bind();
Romain Guy2055aba2013-01-18 16:42:51 -0800231 }
232 }
233
Romain Guy9ace8f52011-07-07 20:50:11 -0700234 inline void generateTexture() {
Romain Guyef09a212012-09-25 12:17:14 -0700235 if (!texture.id) {
236 glGenTextures(1, &texture.id);
237 }
Romain Guy9ace8f52011-07-07 20:50:11 -0700238 }
239
240 inline void deleteTexture() {
Romain Guyef09a212012-09-25 12:17:14 -0700241 if (texture.id) {
242 glDeleteTextures(1, &texture.id);
243 texture.id = 0;
244 }
245 }
246
247 /**
248 * When the caller frees the texture itself, the caller
249 * must call this method to tell this layer that it lost
250 * the texture.
251 */
252 void clearTexture() {
253 texture.id = 0;
Romain Guy9ace8f52011-07-07 20:50:11 -0700254 }
255
256 inline void allocateTexture(GLenum format, GLenum storage) {
Romain Guyb2e2f242012-10-17 18:18:35 -0700257#if DEBUG_LAYERS
258 ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight());
259#endif
Romain Guy2055aba2013-01-18 16:42:51 -0800260 if (texture.id) {
261 glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0,
262 format, storage, NULL);
263 }
264 }
265
Romain Guy9ace8f52011-07-07 20:50:11 -0700266 inline mat4& getTexTransform() {
267 return texTransform;
Romain Guy9fc27812011-04-27 14:21:41 -0700268 }
269
Romain Guy302a9df2011-08-16 13:55:02 -0700270 inline mat4& getTransform() {
271 return transform;
272 }
273
Romain Guy9fc27812011-04-27 14:21:41 -0700274 /**
Romain Guy8550c4c2010-10-08 15:49:53 -0700275 * Bounds of the layer.
Romain Guydda570202010-07-06 11:39:32 -0700276 */
277 Rect layer;
278 /**
Romain Guy8550c4c2010-10-08 15:49:53 -0700279 * Texture coordinates of the layer.
Romain Guydda570202010-07-06 11:39:32 -0700280 */
Romain Guy8550c4c2010-10-08 15:49:53 -0700281 Rect texCoords;
Romain Guyc3fedaf2013-01-29 17:26:25 -0800282 /**
283 * Clipping rectangle.
284 */
285 Rect clipRect;
Romain Guy8550c4c2010-10-08 15:49:53 -0700286
Romain Guydda570202010-07-06 11:39:32 -0700287 /**
Romain Guy5b3b3522010-10-27 18:57:51 -0700288 * Dirty region indicating what parts of the layer
289 * have been drawn.
290 */
291 Region region;
Romain Guy40667672011-03-18 14:34:03 -0700292 /**
293 * If the region is a rectangle, coordinates of the
294 * region are stored here.
295 */
296 Rect regionRect;
Romain Guy171c5922011-01-06 10:04:23 -0800297
298 /**
Romain Guyf219da52011-01-16 12:54:25 -0800299 * If the layer can be rendered as a mesh, this is non-null.
300 */
301 TextureVertex* mesh;
302 uint16_t* meshIndices;
303 GLsizei meshElementCount;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700304
Romain Guy2bf68f02012-03-02 13:37:47 -0800305 /**
306 * Used for deferred updates.
307 */
308 bool deferredUpdateScheduled;
309 OpenGLRenderer* renderer;
310 DisplayList* displayList;
311 Rect dirtyRect;
Romain Guy5bb3c732012-11-29 17:52:58 -0800312 bool debugDrawUpdate;
Romain Guy2bf68f02012-03-02 13:37:47 -0800313
Romain Guy9ace8f52011-07-07 20:50:11 -0700314private:
315 /**
316 * Name of the FBO used to render the layer. If the name is 0
317 * this layer is not backed by an FBO, but a simple texture.
318 */
319 GLuint fbo;
320
321 /**
Romain Guy3bbacf22013-02-06 16:51:04 -0800322 * The render buffer used as the stencil buffer.
Romain Guy8ce00302013-01-15 18:51:42 -0800323 */
Romain Guy3bbacf22013-02-06 16:51:04 -0800324 RenderBuffer* stencil;
Romain Guy8ce00302013-01-15 18:51:42 -0800325
326 /**
Romain Guy9ace8f52011-07-07 20:50:11 -0700327 * Indicates whether this layer has been used already.
328 */
329 bool empty;
330
331 /**
332 * The texture backing this layer.
333 */
334 Texture texture;
335
Romain Guyaa6c24c2011-04-28 18:40:04 -0700336 /**
337 * If set to true (by default), the layer can be reused.
338 */
Romain Guy9ace8f52011-07-07 20:50:11 -0700339 bool cacheable;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700340
341 /**
342 * When set to true, this layer must be treated as a texture
343 * layer.
344 */
Romain Guy9ace8f52011-07-07 20:50:11 -0700345 bool textureLayer;
346
347 /**
Romain Guy7c25aab2012-10-18 15:05:02 -0700348 * When set to true, this layer is dirty and should be cleared
349 * before any rendering occurs.
350 */
351 bool dirty;
352
353 /**
Romain Guy9ace8f52011-07-07 20:50:11 -0700354 * Indicates the render target.
355 */
356 GLenum renderTarget;
357
358 /**
359 * Color filter used to draw this layer. Optional.
360 */
361 SkiaColorFilter* colorFilter;
362
363 /**
364 * Opacity of the layer.
365 */
366 int alpha;
367 /**
368 * Blending mode of the layer.
369 */
370 SkXfermode::Mode mode;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700371
372 /**
373 * Optional texture coordinates transform.
374 */
375 mat4 texTransform;
Romain Guy8f0095c2011-05-02 17:24:22 -0700376
Romain Guy302a9df2011-08-16 13:55:02 -0700377 /**
378 * Optional transform.
379 */
380 mat4 transform;
381
Romain Guydda570202010-07-06 11:39:32 -0700382}; // struct Layer
383
384}; // namespace uirenderer
385}; // namespace android
386
Romain Guy5b3b3522010-10-27 18:57:51 -0700387#endif // ANDROID_HWUI_LAYER_H