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 
     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      */
     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 
    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 
    112     inline uint32_t getWidth() const {
    113         return texture.width;
    114     }
    115 
    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 
    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 
    138     inline void setBlend(bool blend) {
    139         texture.blend = blend;
    140     }
    141 
    142     inline bool isBlend() const {
    143         return texture.blend;
    144     }
    145 
    146     inline void setForceFilter(bool forceFilter) {
    147         this->forceFilter = forceFilter;
    148     }
    149 
    150     inline bool getForceFilter() const {
    151         return forceFilter;
    152     }
    153 
    154     inline void setAlpha(int alpha) {
    155         this->alpha = alpha;
    156     }
    157 
    158     inline void setAlpha(int alpha, SkXfermode::Mode mode) {
    159         this->alpha = alpha;
    160         this->mode = mode;
    161     }
    162 
    163     inline int getAlpha() const {
    164         return alpha;
    165     }
    166 
    167     inline SkXfermode::Mode getMode() const {
    168         return mode;
    169     }
    170 
    171     inline void setEmpty(bool empty) {
    172         this->empty = empty;
    173     }
    174 
    175     inline bool isEmpty() const {
    176         return empty;
    177     }
    178 
    179     inline void setFbo(GLuint fbo) {
    180         this->fbo = fbo;
    181     }
    182 
    183     inline GLuint getFbo() const {
    184         return fbo;
    185     }
    186 
    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 
    197     inline RenderBuffer* getStencilRenderBuffer() const {
    198         return stencil;
    199     }
    200 
    201     inline GLuint getTexture() const {
    202         return texture.id;
    203     }
    204 
    205     inline GLenum getRenderTarget() const {
    206         return renderTarget;
    207     }
    208 
    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 
    221     inline bool isCacheable() const {
    222         return cacheable;
    223     }
    224 
    225     inline void setCacheable(bool cacheable) {
    226         this->cacheable = cacheable;
    227     }
    228 
    229     inline bool isDirty() const {
    230         return dirty;
    231     }
    232 
    233     inline void setDirty(bool dirty) {
    234         this->dirty = dirty;
    235     }
    236 
    237     inline bool isTextureLayer() const {
    238         return type == kType_Texture;
    239     }
    240 
    241     inline SkColorFilter* getColorFilter() const {
    242         return colorFilter;
    243     }
    244 
    245     ANDROID_API void setColorFilter(SkColorFilter* filter);
    246 
    247     inline void setConvexMask(const SkPath* convexMask) {
    248         this->convexMask = convexMask;
    249     }
    250 
    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 
    269     inline mat4& getTexTransform() {
    270         return texTransform;
    271     }
    272 
    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