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 #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      */
     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 
    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 
    115     inline uint32_t getWidth() const {
    116         return texture.mWidth;
    117     }
    118 
    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 
    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 
    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     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 
    231     inline bool isCacheable() const {
    232         return cacheable;
    233     }
    234 
    235     inline void setCacheable(bool cacheable) {
    236         this->cacheable = cacheable;
    237     }
    238 
    239     inline bool isDirty() const {
    240         return dirty;
    241     }
    242 
    243     inline void setDirty(bool dirty) {
    244         this->dirty = dirty;
    245     }
    246 
    247     inline bool isTextureLayer() const {
    248         return type == Type::Texture;
    249     }
    250 
    251     inline SkColorFilter* getColorFilter() const {
    252         return colorFilter;
    253     }
    254 
    255     ANDROID_API void setColorFilter(SkColorFilter* filter);
    256 
    257     inline void setConvexMask(const SkPath* convexMask) {
    258         this->convexMask = convexMask;
    259     }
    260 
    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 
    278     inline mat4& getTexTransform() {
    279         return texTransform;
    280     }
    281 
    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