Layer.h revision 781fd2b7c86a20b0f00b5e009237d69b557e3cc4
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 "SkiaColorFilter.h" 31#include "Texture.h" 32#include "Vertex.h" 33 34namespace android { 35namespace uirenderer { 36 37/////////////////////////////////////////////////////////////////////////////// 38// Layers 39/////////////////////////////////////////////////////////////////////////////// 40 41// Forward declarations 42class OpenGLRenderer; 43class DisplayList; 44 45/** 46 * A layer has dimensions and is backed by an OpenGL texture or FBO. 47 */ 48struct Layer { 49 Layer(const uint32_t layerWidth, const uint32_t layerHeight); 50 ~Layer(); 51 52 static uint32_t computeIdealWidth(uint32_t layerWidth); 53 static uint32_t computeIdealHeight(uint32_t layerHeight); 54 55 /** 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); 61 62 /** 63 * 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 71 const float texX = 1.0f / float(texture.width); 72 const float texY = 1.0f / float(texture.height); 73 const float height = layer.getHeight(); 74 texCoords.set( 75 regionRect.left * texX, (height - regionRect.top) * texY, 76 regionRect.right * texX, (height - regionRect.bottom) * texY); 77 78 regionRect.translate(layer.left, layer.top); 79 } 80 81 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 90 inline uint32_t getWidth() { 91 return texture.width; 92 } 93 94 inline uint32_t getHeight() { 95 return texture.height; 96 } 97 98 /** 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 109 void setSize(uint32_t width, uint32_t height) { 110 texture.width = width; 111 texture.height = height; 112 } 113 114 ANDROID_API void setPaint(SkPaint* paint); 115 116 inline void setBlend(bool blend) { 117 texture.blend = blend; 118 } 119 120 inline bool isBlend() { 121 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 133 inline int getAlpha() { 134 return alpha; 135 } 136 137 inline SkXfermode::Mode getMode() { 138 return mode; 139 } 140 141 inline void setEmpty(bool empty) { 142 this->empty = empty; 143 } 144 145 inline bool isEmpty() { 146 return empty; 147 } 148 149 inline void setFbo(GLuint fbo) { 150 this->fbo = fbo; 151 } 152 153 inline GLuint getFbo() { 154 return fbo; 155 } 156 157 inline void setStencilRenderBuffer(GLuint renderBuffer) { 158 this->stencil = renderBuffer; 159 } 160 161 inline GLuint getStencilRenderBuffer() { 162 return stencil; 163 } 164 165 inline GLuint getTexture() { 166 return texture.id; 167 } 168 169 inline GLenum getRenderTarget() { 170 return renderTarget; 171 } 172 173 inline void setRenderTarget(GLenum renderTarget) { 174 this->renderTarget = renderTarget; 175 } 176 177 void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) { 178 texture.setWrap(wrap, bindTexture, force, renderTarget); 179 } 180 181 void setFilter(GLenum filter, bool bindTexture = false, bool force = false) { 182 texture.setFilter(filter, bindTexture, force, renderTarget); 183 } 184 185 inline bool isCacheable() { 186 return cacheable; 187 } 188 189 inline void setCacheable(bool cacheable) { 190 this->cacheable = cacheable; 191 } 192 193 inline bool isDirty() { 194 return dirty; 195 } 196 197 inline void setDirty(bool dirty) { 198 this->dirty = dirty; 199 } 200 201 inline bool isTextureLayer() { 202 return textureLayer; 203 } 204 205 inline void setTextureLayer(bool textureLayer) { 206 this->textureLayer = textureLayer; 207 } 208 209 inline SkiaColorFilter* getColorFilter() { 210 return colorFilter; 211 } 212 213 ANDROID_API void setColorFilter(SkiaColorFilter* filter); 214 215 inline void bindTexture() { 216 if (texture.id) { 217 glBindTexture(renderTarget, texture.id); 218 } 219 } 220 221 inline void bindStencilRenderBuffer() { 222 if (stencil) { 223 glBindRenderbuffer(GL_RENDERBUFFER, stencil); 224 } 225 } 226 227 inline void generateTexture() { 228 if (!texture.id) { 229 glGenTextures(1, &texture.id); 230 } 231 } 232 233 inline void deleteTexture() { 234 if (texture.id) { 235 glDeleteTextures(1, &texture.id); 236 texture.id = 0; 237 } 238 } 239 240 /** 241 * When the caller frees the texture itself, the caller 242 * must call this method to tell this layer that it lost 243 * the texture. 244 */ 245 void clearTexture() { 246 texture.id = 0; 247 } 248 249 inline void allocateTexture(GLenum format, GLenum storage) { 250#if DEBUG_LAYERS 251 ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight()); 252#endif 253 if (texture.id) { 254 glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0, 255 format, storage, NULL); 256 } 257 } 258 259 inline void allocateStencilRenderBuffer() { 260 if (stencil) { 261 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, getWidth(), getHeight()); 262 } 263 } 264 265 inline mat4& getTexTransform() { 266 return texTransform; 267 } 268 269 inline mat4& getTransform() { 270 return transform; 271 } 272 273 /** 274 * Bounds of the layer. 275 */ 276 Rect layer; 277 /** 278 * Texture coordinates of the layer. 279 */ 280 Rect texCoords; 281 /** 282 * Clipping rectangle. 283 */ 284 Rect clipRect; 285 286 /** 287 * Dirty region indicating what parts of the layer 288 * have been drawn. 289 */ 290 Region region; 291 /** 292 * If the region is a rectangle, coordinates of the 293 * region are stored here. 294 */ 295 Rect regionRect; 296 297 /** 298 * If the layer can be rendered as a mesh, this is non-null. 299 */ 300 TextureVertex* mesh; 301 uint16_t* meshIndices; 302 GLsizei meshElementCount; 303 304 /** 305 * Used for deferred updates. 306 */ 307 bool deferredUpdateScheduled; 308 OpenGLRenderer* renderer; 309 DisplayList* displayList; 310 Rect dirtyRect; 311 bool debugDrawUpdate; 312 313private: 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 /** 321 * Name of the render buffer used as the stencil buffer. If the 322 * name is 0, this layer does not have a stencil buffer. 323 */ 324 GLuint stencil; 325 326 /** 327 * 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 336 /** 337 * If set to true (by default), the layer can be reused. 338 */ 339 bool cacheable; 340 341 /** 342 * When set to true, this layer must be treated as a texture 343 * layer. 344 */ 345 bool textureLayer; 346 347 /** 348 * When set to true, this layer is dirty and should be cleared 349 * before any rendering occurs. 350 */ 351 bool dirty; 352 353 /** 354 * 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; 371 372 /** 373 * Optional texture coordinates transform. 374 */ 375 mat4 texTransform; 376 377 /** 378 * Optional transform. 379 */ 380 mat4 transform; 381 382}; // struct Layer 383 384}; // namespace uirenderer 385}; // namespace android 386 387#endif // ANDROID_HWUI_LAYER_H 388