Layer.h revision 0908764b2b3cf5075df4178a5f0a8547dcb7b317
1/* 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 17#ifndef ANDROID_HWUI_LAYER_H 18#define ANDROID_HWUI_LAYER_H 19 20#include <sys/types.h> 21 22#include <GLES2/gl2.h> 23 24#include <ui/Region.h> 25 26#include <SkPaint.h> 27#include <SkXfermode.h> 28 29#include "Rect.h" 30#include "RenderBuffer.h" 31#include "SkiaColorFilter.h" 32#include "Texture.h" 33#include "Vertex.h" 34 35namespace android { 36namespace uirenderer { 37 38/////////////////////////////////////////////////////////////////////////////// 39// Layers 40/////////////////////////////////////////////////////////////////////////////// 41 42// Forward declarations 43class OpenGLRenderer; 44class DisplayList; 45class DeferredDisplayList; 46class DeferStateStruct; 47 48/** 49 * A layer has dimensions and is backed by an OpenGL texture or FBO. 50 */ 51struct Layer { 52 Layer(const uint32_t layerWidth, const uint32_t layerHeight); 53 ~Layer(); 54 55 static uint32_t computeIdealWidth(uint32_t layerWidth); 56 static uint32_t computeIdealHeight(uint32_t layerHeight); 57 58 /** 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); 64 65 /** 66 * 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 74 const float texX = 1.0f / float(texture.width); 75 const float texY = 1.0f / float(texture.height); 76 const float height = layer.getHeight(); 77 texCoords.set( 78 regionRect.left * texX, (height - regionRect.top) * texY, 79 regionRect.right * texX, (height - regionRect.bottom) * texY); 80 81 regionRect.translate(layer.left, layer.top); 82 } 83 84 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 93 inline uint32_t getWidth() const { 94 return texture.width; 95 } 96 97 inline uint32_t getHeight() const { 98 return texture.height; 99 } 100 101 /** 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 112 void setSize(uint32_t width, uint32_t height) { 113 texture.width = width; 114 texture.height = height; 115 } 116 117 ANDROID_API void setPaint(SkPaint* paint); 118 119 inline void setBlend(bool blend) { 120 texture.blend = blend; 121 } 122 123 inline bool isBlend() const { 124 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 136 inline int getAlpha() const { 137 return alpha; 138 } 139 140 inline SkXfermode::Mode getMode() const { 141 return mode; 142 } 143 144 inline void setEmpty(bool empty) { 145 this->empty = empty; 146 } 147 148 inline bool isEmpty() const { 149 return empty; 150 } 151 152 inline void setFbo(GLuint fbo) { 153 this->fbo = fbo; 154 } 155 156 inline GLuint getFbo() const { 157 return fbo; 158 } 159 160 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 } 168 } 169 170 inline RenderBuffer* getStencilRenderBuffer() const { 171 return stencil; 172 } 173 174 inline GLuint getTexture() const { 175 return texture.id; 176 } 177 178 inline GLenum getRenderTarget() const { 179 return renderTarget; 180 } 181 182 inline void setRenderTarget(GLenum renderTarget) { 183 this->renderTarget = renderTarget; 184 } 185 186 void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) { 187 texture.setWrap(wrap, bindTexture, force, renderTarget); 188 } 189 190 void setFilter(GLenum filter, bool bindTexture = false, bool force = false) { 191 texture.setFilter(filter, bindTexture, force, renderTarget); 192 } 193 194 inline bool isCacheable() const { 195 return cacheable; 196 } 197 198 inline void setCacheable(bool cacheable) { 199 this->cacheable = cacheable; 200 } 201 202 inline bool isDirty() const { 203 return dirty; 204 } 205 206 inline void setDirty(bool dirty) { 207 this->dirty = dirty; 208 } 209 210 inline bool isTextureLayer() const { 211 return textureLayer; 212 } 213 214 inline void setTextureLayer(bool textureLayer) { 215 this->textureLayer = textureLayer; 216 } 217 218 inline SkiaColorFilter* getColorFilter() const { 219 return colorFilter; 220 } 221 222 ANDROID_API void setColorFilter(SkiaColorFilter* filter); 223 224 inline void bindTexture() const { 225 if (texture.id) { 226 glBindTexture(renderTarget, texture.id); 227 } 228 } 229 230 inline void bindStencilRenderBuffer() const { 231 if (stencil) { 232 stencil->bind(); 233 } 234 } 235 236 inline void generateTexture() { 237 if (!texture.id) { 238 glGenTextures(1, &texture.id); 239 } 240 } 241 242 inline void deleteTexture() { 243 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; 256 } 257 258 inline void allocateTexture() { 259#if DEBUG_LAYERS 260 ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight()); 261#endif 262 if (texture.id) { 263 glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 264 glTexImage2D(renderTarget, 0, GL_RGBA, getWidth(), getHeight(), 0, 265 GL_RGBA, GL_UNSIGNED_BYTE, NULL); 266 } 267 } 268 269 inline mat4& getTexTransform() { 270 return texTransform; 271 } 272 273 inline mat4& getTransform() { 274 return transform; 275 } 276 277 void defer(); 278 void flush(); 279 void render(); 280 281 /** 282 * Bounds of the layer. 283 */ 284 Rect layer; 285 /** 286 * Texture coordinates of the layer. 287 */ 288 Rect texCoords; 289 /** 290 * Clipping rectangle. 291 */ 292 Rect clipRect; 293 294 /** 295 * Dirty region indicating what parts of the layer 296 * have been drawn. 297 */ 298 Region region; 299 /** 300 * If the region is a rectangle, coordinates of the 301 * region are stored here. 302 */ 303 Rect regionRect; 304 305 /** 306 * If the layer can be rendered as a mesh, this is non-null. 307 */ 308 TextureVertex* mesh; 309 uint16_t* meshIndices; 310 GLsizei meshElementCount; 311 312 /** 313 * Used for deferred updates. 314 */ 315 bool deferredUpdateScheduled; 316 OpenGLRenderer* renderer; 317 DisplayList* displayList; 318 Rect dirtyRect; 319 bool debugDrawUpdate; 320 321private: 322 /** 323 * Name of the FBO used to render the layer. If the name is 0 324 * this layer is not backed by an FBO, but a simple texture. 325 */ 326 GLuint fbo; 327 328 /** 329 * The render buffer used as the stencil buffer. 330 */ 331 RenderBuffer* stencil; 332 333 /** 334 * Indicates whether this layer has been used already. 335 */ 336 bool empty; 337 338 /** 339 * The texture backing this layer. 340 */ 341 Texture texture; 342 343 /** 344 * If set to true (by default), the layer can be reused. 345 */ 346 bool cacheable; 347 348 /** 349 * When set to true, this layer must be treated as a texture 350 * layer. 351 */ 352 bool textureLayer; 353 354 /** 355 * When set to true, this layer is dirty and should be cleared 356 * before any rendering occurs. 357 */ 358 bool dirty; 359 360 /** 361 * Indicates the render target. 362 */ 363 GLenum renderTarget; 364 365 /** 366 * Color filter used to draw this layer. Optional. 367 */ 368 SkiaColorFilter* colorFilter; 369 370 /** 371 * Opacity of the layer. 372 */ 373 int alpha; 374 /** 375 * Blending mode of the layer. 376 */ 377 SkXfermode::Mode mode; 378 379 /** 380 * Optional texture coordinates transform. 381 */ 382 mat4 texTransform; 383 384 /** 385 * Optional transform. 386 */ 387 mat4 transform; 388 389 /** 390 * Used to defer display lists when the layer is updated with a 391 * display list. 392 */ 393 DeferredDisplayList* deferredList; 394 395}; // struct Layer 396 397}; // namespace uirenderer 398}; // namespace android 399 400#endif // ANDROID_HWUI_LAYER_H 401