Home | History | Annotate | Download | only in hwui
      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      */
     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 
    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 
    114     inline uint32_t getWidth() const {
    115         return texture.width;
    116     }
    117 
    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 
    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 
    140     inline void setBlend(bool blend) {
    141         texture.blend = blend;
    142     }
    143 
    144     inline bool isBlend() const {
    145         return texture.blend;
    146     }
    147 
    148     inline void setForceFilter(bool forceFilter) {
    149         this->forceFilter = forceFilter;
    150     }
    151 
    152     inline bool getForceFilter() const {
    153         return forceFilter;
    154     }
    155 
    156     inline void setAlpha(int alpha) {
    157         this->alpha = alpha;
    158     }
    159 
    160     inline void setAlpha(int alpha, SkXfermode::Mode mode) {
    161         this->alpha = alpha;
    162         this->mode = mode;
    163     }
    164 
    165     inline int getAlpha() const {
    166         return alpha;
    167     }
    168 
    169     inline SkXfermode::Mode getMode() const {
    170         return mode;
    171     }
    172 
    173     inline void setEmpty(bool empty) {
    174         this->empty = empty;
    175     }
    176 
    177     inline bool isEmpty() const {
    178         return empty;
    179     }
    180 
    181     inline void setFbo(GLuint fbo) {
    182         this->fbo = fbo;
    183     }
    184 
    185     inline GLuint getFbo() const {
    186         return fbo;
    187     }
    188 
    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 
    199     inline RenderBuffer* getStencilRenderBuffer() const {
    200         return stencil;
    201     }
    202 
    203     inline GLuint getTextureId() const {
    204         return texture.id;
    205     }
    206 
    207     inline Texture& getTexture() {
    208         return texture;
    209     }
    210 
    211     inline GLenum getRenderTarget() const {
    212         return renderTarget;
    213     }
    214 
    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 
    227     inline bool isCacheable() const {
    228         return cacheable;
    229     }
    230 
    231     inline void setCacheable(bool cacheable) {
    232         this->cacheable = cacheable;
    233     }
    234 
    235     inline bool isDirty() const {
    236         return dirty;
    237     }
    238 
    239     inline void setDirty(bool dirty) {
    240         this->dirty = dirty;
    241     }
    242 
    243     inline bool isTextureLayer() const {
    244         return type == kType_Texture;
    245     }
    246 
    247     inline SkColorFilter* getColorFilter() const {
    248         return colorFilter;
    249     }
    250 
    251     ANDROID_API void setColorFilter(SkColorFilter* filter);
    252 
    253     inline void setConvexMask(const SkPath* convexMask) {
    254         this->convexMask = convexMask;
    255     }
    256 
    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 
    275     inline mat4& getTexTransform() {
    276         return texTransform;
    277     }
    278 
    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