Layer.h revision da8d8b9699fe8e9557389465007e333d3f03dcc1
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; 45 46/** 47 * A layer has dimensions and is backed by an OpenGL texture or FBO. 48 */ 49struct Layer { 50 Layer(const uint32_t layerWidth, const uint32_t layerHeight); 51 ~Layer(); 52 53 static uint32_t computeIdealWidth(uint32_t layerWidth); 54 static uint32_t computeIdealHeight(uint32_t layerHeight); 55 56 /** 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); 62 63 /** 64 * 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 72 const float texX = 1.0f / float(texture.width); 73 const float texY = 1.0f / float(texture.height); 74 const float height = layer.getHeight(); 75 texCoords.set( 76 regionRect.left * texX, (height - regionRect.top) * texY, 77 regionRect.right * texX, (height - regionRect.bottom) * texY); 78 79 regionRect.translate(layer.left, layer.top); 80 } 81 82 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 91 inline uint32_t getWidth() const { 92 return texture.width; 93 } 94 95 inline uint32_t getHeight() const { 96 return texture.height; 97 } 98 99 /** 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 110 void setSize(uint32_t width, uint32_t height) { 111 texture.width = width; 112 texture.height = height; 113 } 114 115 ANDROID_API void setPaint(SkPaint* paint); 116 117 inline void setBlend(bool blend) { 118 texture.blend = blend; 119 } 120 121 inline bool isBlend() const { 122 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 134 inline int getAlpha() const { 135 return alpha; 136 } 137 138 inline SkXfermode::Mode getMode() const { 139 return mode; 140 } 141 142 inline void setEmpty(bool empty) { 143 this->empty = empty; 144 } 145 146 inline bool isEmpty() const { 147 return empty; 148 } 149 150 inline void setFbo(GLuint fbo) { 151 this->fbo = fbo; 152 } 153 154 inline GLuint getFbo() const { 155 return fbo; 156 } 157 158 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 } 166 } 167 168 inline RenderBuffer* getStencilRenderBuffer() const { 169 return stencil; 170 } 171 172 inline GLuint getTexture() const { 173 return texture.id; 174 } 175 176 inline GLenum getRenderTarget() const { 177 return renderTarget; 178 } 179 180 inline void setRenderTarget(GLenum renderTarget) { 181 this->renderTarget = renderTarget; 182 } 183 184 void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) { 185 texture.setWrap(wrap, bindTexture, force, renderTarget); 186 } 187 188 void setFilter(GLenum filter, bool bindTexture = false, bool force = false) { 189 texture.setFilter(filter, bindTexture, force, renderTarget); 190 } 191 192 inline bool isCacheable() const { 193 return cacheable; 194 } 195 196 inline void setCacheable(bool cacheable) { 197 this->cacheable = cacheable; 198 } 199 200 inline bool isDirty() const { 201 return dirty; 202 } 203 204 inline void setDirty(bool dirty) { 205 this->dirty = dirty; 206 } 207 208 inline bool isTextureLayer() const { 209 return textureLayer; 210 } 211 212 inline void setTextureLayer(bool textureLayer) { 213 this->textureLayer = textureLayer; 214 } 215 216 inline SkiaColorFilter* getColorFilter() const { 217 return colorFilter; 218 } 219 220 ANDROID_API void setColorFilter(SkiaColorFilter* filter); 221 222 inline void bindTexture() const { 223 if (texture.id) { 224 glBindTexture(renderTarget, texture.id); 225 } 226 } 227 228 inline void bindStencilRenderBuffer() const { 229 if (stencil) { 230 stencil->bind(); 231 } 232 } 233 234 inline void generateTexture() { 235 if (!texture.id) { 236 glGenTextures(1, &texture.id); 237 } 238 } 239 240 inline void deleteTexture() { 241 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; 254 } 255 256 inline void allocateTexture(GLenum format, GLenum storage) { 257#if DEBUG_LAYERS 258 ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight()); 259#endif 260 if (texture.id) { 261 glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0, 262 format, storage, NULL); 263 } 264 } 265 266 inline mat4& getTexTransform() { 267 return texTransform; 268 } 269 270 inline mat4& getTransform() { 271 return transform; 272 } 273 274 /** 275 * Bounds of the layer. 276 */ 277 Rect layer; 278 /** 279 * Texture coordinates of the layer. 280 */ 281 Rect texCoords; 282 /** 283 * Clipping rectangle. 284 */ 285 Rect clipRect; 286 287 /** 288 * Dirty region indicating what parts of the layer 289 * have been drawn. 290 */ 291 Region region; 292 /** 293 * If the region is a rectangle, coordinates of the 294 * region are stored here. 295 */ 296 Rect regionRect; 297 298 /** 299 * If the layer can be rendered as a mesh, this is non-null. 300 */ 301 TextureVertex* mesh; 302 uint16_t* meshIndices; 303 GLsizei meshElementCount; 304 305 /** 306 * Used for deferred updates. 307 */ 308 bool deferredUpdateScheduled; 309 OpenGLRenderer* renderer; 310 DisplayList* displayList; 311 Rect dirtyRect; 312 bool debugDrawUpdate; 313 314private: 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 /** 322 * The render buffer used as the stencil buffer. 323 */ 324 RenderBuffer* 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