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