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