Layer.h revision c3fedafc5f50100219449125a000e3138f6fb987
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 <SkXfermode.h> 27 28#include "Rect.h" 29#include "SkiaColorFilter.h" 30#include "Texture.h" 31#include "Vertex.h" 32 33namespace android { 34namespace uirenderer { 35 36/////////////////////////////////////////////////////////////////////////////// 37// Layers 38/////////////////////////////////////////////////////////////////////////////// 39 40// Forward declarations 41class OpenGLRenderer; 42class DisplayList; 43 44/** 45 * A layer has dimensions and is backed by an OpenGL texture or FBO. 46 */ 47struct Layer { 48 Layer(const uint32_t layerWidth, const uint32_t layerHeight); 49 ~Layer(); 50 51 static uint32_t computeIdealWidth(uint32_t layerWidth); 52 static uint32_t computeIdealHeight(uint32_t layerHeight); 53 54 /** 55 * Calling this method will remove (either by recycling or 56 * destroying) the associated FBO, if present, and any render 57 * buffer (stencil for instance.) 58 */ 59 void removeFbo(bool flush = true); 60 61 /** 62 * Sets this layer's region to a rectangle. Computes the appropriate 63 * texture coordinates. 64 */ 65 void setRegionAsRect() { 66 const android::Rect& bounds = region.getBounds(); 67 regionRect.set(bounds.leftTop().x, bounds.leftTop().y, 68 bounds.rightBottom().x, bounds.rightBottom().y); 69 70 const float texX = 1.0f / float(texture.width); 71 const float texY = 1.0f / float(texture.height); 72 const float height = layer.getHeight(); 73 texCoords.set( 74 regionRect.left * texX, (height - regionRect.top) * texY, 75 regionRect.right * texX, (height - regionRect.bottom) * texY); 76 77 regionRect.translate(layer.left, layer.top); 78 } 79 80 void updateDeferred(OpenGLRenderer* renderer, DisplayList* displayList, 81 int left, int top, int right, int bottom) { 82 this->renderer = renderer; 83 this->displayList = displayList; 84 const Rect r(left, top, right, bottom); 85 dirtyRect.unionWith(r); 86 deferredUpdateScheduled = true; 87 } 88 89 inline uint32_t getWidth() { 90 return texture.width; 91 } 92 93 inline uint32_t getHeight() { 94 return texture.height; 95 } 96 97 /** 98 * Resize the layer and its texture if needed. 99 * 100 * @param width The new width of the layer 101 * @param height The new height of the layer 102 * 103 * @return True if the layer was resized or nothing happened, false if 104 * a failure occurred during the resizing operation 105 */ 106 bool resize(const uint32_t width, const uint32_t height); 107 108 void setSize(uint32_t width, uint32_t height) { 109 texture.width = width; 110 texture.height = height; 111 } 112 113 ANDROID_API void setPaint(SkPaint* paint); 114 115 inline void setBlend(bool blend) { 116 texture.blend = blend; 117 } 118 119 inline bool isBlend() { 120 return texture.blend; 121 } 122 123 inline void setAlpha(int alpha) { 124 this->alpha = alpha; 125 } 126 127 inline void setAlpha(int alpha, SkXfermode::Mode mode) { 128 this->alpha = alpha; 129 this->mode = mode; 130 } 131 132 inline int getAlpha() { 133 return alpha; 134 } 135 136 inline SkXfermode::Mode getMode() { 137 return mode; 138 } 139 140 inline void setEmpty(bool empty) { 141 this->empty = empty; 142 } 143 144 inline bool isEmpty() { 145 return empty; 146 } 147 148 inline void setFbo(GLuint fbo) { 149 this->fbo = fbo; 150 } 151 152 inline GLuint getFbo() { 153 return fbo; 154 } 155 156 inline void setStencilRenderBuffer(GLuint renderBuffer) { 157 this->stencil = renderBuffer; 158 } 159 160 inline GLuint getStencilRenderBuffer() { 161 return stencil; 162 } 163 164 inline GLuint getTexture() { 165 return texture.id; 166 } 167 168 inline GLenum getRenderTarget() { 169 return renderTarget; 170 } 171 172 inline void setRenderTarget(GLenum renderTarget) { 173 this->renderTarget = renderTarget; 174 } 175 176 void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) { 177 texture.setWrap(wrap, bindTexture, force, renderTarget); 178 } 179 180 void setFilter(GLenum filter, bool bindTexture = false, bool force = false) { 181 texture.setFilter(filter, bindTexture, force, renderTarget); 182 } 183 184 inline bool isCacheable() { 185 return cacheable; 186 } 187 188 inline void setCacheable(bool cacheable) { 189 this->cacheable = cacheable; 190 } 191 192 inline bool isDirty() { 193 return dirty; 194 } 195 196 inline void setDirty(bool dirty) { 197 this->dirty = dirty; 198 } 199 200 inline bool isTextureLayer() { 201 return textureLayer; 202 } 203 204 inline void setTextureLayer(bool textureLayer) { 205 this->textureLayer = textureLayer; 206 } 207 208 inline SkiaColorFilter* getColorFilter() { 209 return colorFilter; 210 } 211 212 ANDROID_API void setColorFilter(SkiaColorFilter* filter); 213 214 inline void bindTexture() { 215 if (texture.id) { 216 glBindTexture(renderTarget, texture.id); 217 } 218 } 219 220 inline void bindStencilRenderBuffer() { 221 if (stencil) { 222 glBindRenderbuffer(GL_RENDERBUFFER, stencil); 223 } 224 } 225 226 inline void generateTexture() { 227 if (!texture.id) { 228 glGenTextures(1, &texture.id); 229 } 230 } 231 232 inline void deleteTexture() { 233 if (texture.id) { 234 glDeleteTextures(1, &texture.id); 235 texture.id = 0; 236 } 237 } 238 239 /** 240 * When the caller frees the texture itself, the caller 241 * must call this method to tell this layer that it lost 242 * the texture. 243 */ 244 void clearTexture() { 245 texture.id = 0; 246 } 247 248 inline void allocateTexture(GLenum format, GLenum storage) { 249#if DEBUG_LAYERS 250 ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight()); 251#endif 252 if (texture.id) { 253 glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0, 254 format, storage, NULL); 255 } 256 } 257 258 inline void allocateStencilRenderBuffer() { 259 if (stencil) { 260 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, getWidth(), getHeight()); 261 } 262 } 263 264 inline mat4& getTexTransform() { 265 return texTransform; 266 } 267 268 inline mat4& getTransform() { 269 return transform; 270 } 271 272 /** 273 * Bounds of the layer. 274 */ 275 Rect layer; 276 /** 277 * Texture coordinates of the layer. 278 */ 279 Rect texCoords; 280 /** 281 * Clipping rectangle. 282 */ 283 Rect clipRect; 284 285 /** 286 * Dirty region indicating what parts of the layer 287 * have been drawn. 288 */ 289 Region region; 290 /** 291 * If the region is a rectangle, coordinates of the 292 * region are stored here. 293 */ 294 Rect regionRect; 295 296 /** 297 * If the layer can be rendered as a mesh, this is non-null. 298 */ 299 TextureVertex* mesh; 300 uint16_t* meshIndices; 301 GLsizei meshElementCount; 302 303 /** 304 * Used for deferred updates. 305 */ 306 bool deferredUpdateScheduled; 307 OpenGLRenderer* renderer; 308 DisplayList* displayList; 309 Rect dirtyRect; 310 bool debugDrawUpdate; 311 312private: 313 /** 314 * Name of the FBO used to render the layer. If the name is 0 315 * this layer is not backed by an FBO, but a simple texture. 316 */ 317 GLuint fbo; 318 319 /** 320 * Name of the render buffer used as the stencil buffer. If the 321 * name is 0, this layer does not have a stencil buffer. 322 */ 323 GLuint stencil; 324 325 /** 326 * Indicates whether this layer has been used already. 327 */ 328 bool empty; 329 330 /** 331 * The texture backing this layer. 332 */ 333 Texture texture; 334 335 /** 336 * If set to true (by default), the layer can be reused. 337 */ 338 bool cacheable; 339 340 /** 341 * When set to true, this layer must be treated as a texture 342 * layer. 343 */ 344 bool textureLayer; 345 346 /** 347 * When set to true, this layer is dirty and should be cleared 348 * before any rendering occurs. 349 */ 350 bool dirty; 351 352 /** 353 * Indicates the render target. 354 */ 355 GLenum renderTarget; 356 357 /** 358 * Color filter used to draw this layer. Optional. 359 */ 360 SkiaColorFilter* colorFilter; 361 362 /** 363 * Opacity of the layer. 364 */ 365 int alpha; 366 /** 367 * Blending mode of the layer. 368 */ 369 SkXfermode::Mode mode; 370 371 /** 372 * Optional texture coordinates transform. 373 */ 374 mat4 texTransform; 375 376 /** 377 * Optional transform. 378 */ 379 mat4 transform; 380 381}; // struct Layer 382 383}; // namespace uirenderer 384}; // namespace android 385 386#endif // ANDROID_HWUI_LAYER_H 387