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