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