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 <cutils/compiler.h> 21 #include <sys/types.h> 22 #include <utils/StrongPointer.h> 23 24 #include <GLES2/gl2.h> 25 26 #include <ui/Region.h> 27 28 #include <SkPaint.h> 29 #include <SkXfermode.h> 30 31 #include "Matrix.h" 32 #include "Rect.h" 33 #include "RenderBuffer.h" 34 #include "Texture.h" 35 #include "Vertex.h" 36 37 namespace android { 38 namespace uirenderer { 39 40 /////////////////////////////////////////////////////////////////////////////// 41 // Layers 42 /////////////////////////////////////////////////////////////////////////////// 43 44 // Forward declarations 45 class Caches; 46 class RenderState; 47 class OpenGLRenderer; 48 class RenderNode; 49 class DeferredDisplayList; 50 class DeferStateStruct; 51 52 /** 53 * A layer has dimensions and is backed by an OpenGL texture or FBO. 54 */ 55 class Layer : public VirtualLightRefBase { 56 public: 57 enum Type { 58 kType_Texture, 59 kType_DisplayList, 60 }; 61 62 // layer lifecycle, controlled from outside 63 enum State { 64 kState_Uncached = 0, 65 kState_InCache = 1, 66 kState_FailedToCache = 2, 67 kState_RemovedFromCache = 3, 68 kState_DeletedFromCache = 4, 69 kState_InGarbageList = 5, 70 }; 71 State state; // public for logging/debugging purposes 72 73 Layer(Type type, RenderState& renderState, const uint32_t layerWidth, const uint32_t layerHeight); 74 ~Layer(); 75 76 static uint32_t computeIdealWidth(uint32_t layerWidth); 77 static uint32_t computeIdealHeight(uint32_t layerHeight); 78 79 /** 80 * Calling this method will remove (either by recycling or 81 * destroying) the associated FBO, if present, and any render 82 * buffer (stencil for instance.) 83 */ 84 void removeFbo(bool flush = true); 85 86 /** 87 * Sets this layer's region to a rectangle. Computes the appropriate 88 * texture coordinates. 89 */ setRegionAsRect()90 void setRegionAsRect() { 91 const android::Rect& bounds = region.getBounds(); 92 regionRect.set(bounds.leftTop().x, bounds.leftTop().y, 93 bounds.rightBottom().x, bounds.rightBottom().y); 94 95 const float texX = 1.0f / float(texture.width); 96 const float texY = 1.0f / float(texture.height); 97 const float height = layer.getHeight(); 98 texCoords.set( 99 regionRect.left * texX, (height - regionRect.top) * texY, 100 regionRect.right * texX, (height - regionRect.bottom) * texY); 101 102 regionRect.translate(layer.left, layer.top); 103 } 104 setWindowTransform(Matrix4 & windowTransform)105 void setWindowTransform(Matrix4& windowTransform) { 106 cachedInvTransformInWindow.loadInverse(windowTransform); 107 rendererLightPosDirty = true; 108 } 109 110 void updateDeferred(RenderNode* renderNode, int left, int top, int right, int bottom); 111 getWidth()112 inline uint32_t getWidth() const { 113 return texture.width; 114 } 115 getHeight()116 inline uint32_t getHeight() const { 117 return texture.height; 118 } 119 120 /** 121 * Resize the layer and its texture if needed. 122 * 123 * @param width The new width of the layer 124 * @param height The new height of the layer 125 * 126 * @return True if the layer was resized or nothing happened, false if 127 * a failure occurred during the resizing operation 128 */ 129 bool resize(const uint32_t width, const uint32_t height); 130 setSize(uint32_t width,uint32_t height)131 void setSize(uint32_t width, uint32_t height) { 132 texture.width = width; 133 texture.height = height; 134 } 135 136 ANDROID_API void setPaint(const SkPaint* paint); 137 setBlend(bool blend)138 inline void setBlend(bool blend) { 139 texture.blend = blend; 140 } 141 isBlend()142 inline bool isBlend() const { 143 return texture.blend; 144 } 145 setForceFilter(bool forceFilter)146 inline void setForceFilter(bool forceFilter) { 147 this->forceFilter = forceFilter; 148 } 149 getForceFilter()150 inline bool getForceFilter() const { 151 return forceFilter; 152 } 153 setAlpha(int alpha)154 inline void setAlpha(int alpha) { 155 this->alpha = alpha; 156 } 157 setAlpha(int alpha,SkXfermode::Mode mode)158 inline void setAlpha(int alpha, SkXfermode::Mode mode) { 159 this->alpha = alpha; 160 this->mode = mode; 161 } 162 getAlpha()163 inline int getAlpha() const { 164 return alpha; 165 } 166 getMode()167 inline SkXfermode::Mode getMode() const { 168 return mode; 169 } 170 setEmpty(bool empty)171 inline void setEmpty(bool empty) { 172 this->empty = empty; 173 } 174 isEmpty()175 inline bool isEmpty() const { 176 return empty; 177 } 178 setFbo(GLuint fbo)179 inline void setFbo(GLuint fbo) { 180 this->fbo = fbo; 181 } 182 getFbo()183 inline GLuint getFbo() const { 184 return fbo; 185 } 186 setStencilRenderBuffer(RenderBuffer * renderBuffer)187 inline void setStencilRenderBuffer(RenderBuffer* renderBuffer) { 188 if (RenderBuffer::isStencilBuffer(renderBuffer->getFormat())) { 189 this->stencil = renderBuffer; 190 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, 191 GL_RENDERBUFFER, stencil->getName()); 192 } else { 193 ALOGE("The specified render buffer is not a stencil buffer"); 194 } 195 } 196 getStencilRenderBuffer()197 inline RenderBuffer* getStencilRenderBuffer() const { 198 return stencil; 199 } 200 getTexture()201 inline GLuint getTexture() const { 202 return texture.id; 203 } 204 getRenderTarget()205 inline GLenum getRenderTarget() const { 206 return renderTarget; 207 } 208 setRenderTarget(GLenum renderTarget)209 inline void setRenderTarget(GLenum renderTarget) { 210 this->renderTarget = renderTarget; 211 } 212 213 void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) { 214 texture.setWrap(wrap, bindTexture, force, renderTarget); 215 } 216 217 void setFilter(GLenum filter, bool bindTexture = false, bool force = false) { 218 texture.setFilter(filter, bindTexture, force, renderTarget); 219 } 220 isCacheable()221 inline bool isCacheable() const { 222 return cacheable; 223 } 224 setCacheable(bool cacheable)225 inline void setCacheable(bool cacheable) { 226 this->cacheable = cacheable; 227 } 228 isDirty()229 inline bool isDirty() const { 230 return dirty; 231 } 232 setDirty(bool dirty)233 inline void setDirty(bool dirty) { 234 this->dirty = dirty; 235 } 236 isTextureLayer()237 inline bool isTextureLayer() const { 238 return type == kType_Texture; 239 } 240 getColorFilter()241 inline SkColorFilter* getColorFilter() const { 242 return colorFilter; 243 } 244 245 ANDROID_API void setColorFilter(SkColorFilter* filter); 246 setConvexMask(const SkPath * convexMask)247 inline void setConvexMask(const SkPath* convexMask) { 248 this->convexMask = convexMask; 249 } 250 getConvexMask()251 inline const SkPath* getConvexMask() { 252 return convexMask; 253 } 254 255 void bindStencilRenderBuffer() const; 256 257 void bindTexture() const; 258 void generateTexture(); 259 void allocateTexture(); 260 void deleteTexture(); 261 262 /** 263 * When the caller frees the texture itself, the caller 264 * must call this method to tell this layer that it lost 265 * the texture. 266 */ 267 ANDROID_API void clearTexture(); 268 getTexTransform()269 inline mat4& getTexTransform() { 270 return texTransform; 271 } 272 getTransform()273 inline mat4& getTransform() { 274 return transform; 275 } 276 277 void defer(const OpenGLRenderer& rootRenderer); 278 void cancelDefer(); 279 void flush(); 280 void render(const OpenGLRenderer& rootRenderer); 281 282 /** 283 * Posts a decStrong call to the appropriate thread. 284 * Thread-safe. 285 */ 286 void postDecStrong(); 287 288 /** 289 * Lost the GL context but the layer is still around, mark it invalid internally 290 * so the dtor knows not to do any GL work 291 */ 292 void onGlContextLost(); 293 294 /** 295 * Bounds of the layer. 296 */ 297 Rect layer; 298 /** 299 * Texture coordinates of the layer. 300 */ 301 Rect texCoords; 302 /** 303 * Clipping rectangle. 304 */ 305 Rect clipRect; 306 307 /** 308 * Dirty region indicating what parts of the layer 309 * have been drawn. 310 */ 311 Region region; 312 /** 313 * If the region is a rectangle, coordinates of the 314 * region are stored here. 315 */ 316 Rect regionRect; 317 318 /** 319 * If the layer can be rendered as a mesh, this is non-null. 320 */ 321 TextureVertex* mesh; 322 GLsizei meshElementCount; 323 324 /** 325 * Used for deferred updates. 326 */ 327 bool deferredUpdateScheduled; 328 OpenGLRenderer* renderer; 329 sp<RenderNode> renderNode; 330 Rect dirtyRect; 331 bool debugDrawUpdate; 332 bool hasDrawnSinceUpdate; 333 bool wasBuildLayered; 334 335 private: 336 void requireRenderer(); 337 void updateLightPosFromRenderer(const OpenGLRenderer& rootRenderer); 338 339 Caches& caches; 340 341 RenderState& renderState; 342 343 /** 344 * Name of the FBO used to render the layer. If the name is 0 345 * this layer is not backed by an FBO, but a simple texture. 346 */ 347 GLuint fbo; 348 349 /** 350 * The render buffer used as the stencil buffer. 351 */ 352 RenderBuffer* stencil; 353 354 /** 355 * Indicates whether this layer has been used already. 356 */ 357 bool empty; 358 359 /** 360 * The texture backing this layer. 361 */ 362 Texture texture; 363 364 /** 365 * If set to true (by default), the layer can be reused. 366 */ 367 bool cacheable; 368 369 /** 370 * Denotes whether the layer is a DisplayList, or Texture layer. 371 */ 372 const Type type; 373 374 /** 375 * When set to true, this layer is dirty and should be cleared 376 * before any rendering occurs. 377 */ 378 bool dirty; 379 380 /** 381 * Indicates the render target. 382 */ 383 GLenum renderTarget; 384 385 /** 386 * Color filter used to draw this layer. Optional. 387 */ 388 SkColorFilter* colorFilter; 389 390 /** 391 * Indicates raster data backing the layer is scaled, requiring filtration. 392 */ 393 bool forceFilter; 394 395 /** 396 * Opacity of the layer. 397 */ 398 int alpha; 399 400 /** 401 * Blending mode of the layer. 402 */ 403 SkXfermode::Mode mode; 404 405 /** 406 * Optional texture coordinates transform. 407 */ 408 mat4 texTransform; 409 410 /** 411 * Optional transform. 412 */ 413 mat4 transform; 414 415 /** 416 * Cached transform of layer in window, updated only on creation / resize 417 */ 418 mat4 cachedInvTransformInWindow; 419 bool rendererLightPosDirty; 420 421 /** 422 * Used to defer display lists when the layer is updated with a 423 * display list. 424 */ 425 DeferredDisplayList* deferredList; 426 427 /** 428 * This convex path should be used to mask the layer's draw to the screen. 429 * 430 * Data not owned/managed by layer object. 431 */ 432 const SkPath* convexMask; 433 434 }; // struct Layer 435 436 }; // namespace uirenderer 437 }; // namespace android 438 439 #endif // ANDROID_HWUI_LAYER_H 440