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