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 <sys/types.h>
     21 
     22 #include <GLES2/gl2.h>
     23 
     24 #include <ui/Region.h>
     25 
     26 #include <SkPaint.h>
     27 #include <SkXfermode.h>
     28 
     29 #include "Rect.h"
     30 #include "RenderBuffer.h"
     31 #include "SkiaColorFilter.h"
     32 #include "Texture.h"
     33 #include "Vertex.h"
     34 
     35 namespace android {
     36 namespace uirenderer {
     37 
     38 ///////////////////////////////////////////////////////////////////////////////
     39 // Layers
     40 ///////////////////////////////////////////////////////////////////////////////
     41 
     42 // Forward declarations
     43 class Caches;
     44 class OpenGLRenderer;
     45 class DisplayList;
     46 class DeferredDisplayList;
     47 class DeferStateStruct;
     48 
     49 /**
     50  * A layer has dimensions and is backed by an OpenGL texture or FBO.
     51  */
     52 struct Layer {
     53     Layer(const uint32_t layerWidth, const uint32_t layerHeight);
     54     ~Layer();
     55 
     56     static uint32_t computeIdealWidth(uint32_t layerWidth);
     57     static uint32_t computeIdealHeight(uint32_t layerHeight);
     58 
     59     /**
     60      * Calling this method will remove (either by recycling or
     61      * destroying) the associated FBO, if present, and any render
     62      * buffer (stencil for instance.)
     63      */
     64     void removeFbo(bool flush = true);
     65 
     66     /**
     67      * Sets this layer's region to a rectangle. Computes the appropriate
     68      * texture coordinates.
     69      */
     70     void setRegionAsRect() {
     71         const android::Rect& bounds = region.getBounds();
     72         regionRect.set(bounds.leftTop().x, bounds.leftTop().y,
     73                bounds.rightBottom().x, bounds.rightBottom().y);
     74 
     75         const float texX = 1.0f / float(texture.width);
     76         const float texY = 1.0f / float(texture.height);
     77         const float height = layer.getHeight();
     78         texCoords.set(
     79                regionRect.left * texX, (height - regionRect.top) * texY,
     80                regionRect.right * texX, (height - regionRect.bottom) * texY);
     81 
     82         regionRect.translate(layer.left, layer.top);
     83     }
     84 
     85     void updateDeferred(OpenGLRenderer* renderer, DisplayList* displayList,
     86             int left, int top, int right, int bottom) {
     87         this->renderer = renderer;
     88         this->displayList = displayList;
     89         const Rect r(left, top, right, bottom);
     90         dirtyRect.unionWith(r);
     91         deferredUpdateScheduled = true;
     92     }
     93 
     94     inline uint32_t getWidth() const {
     95         return texture.width;
     96     }
     97 
     98     inline uint32_t getHeight() const {
     99         return texture.height;
    100     }
    101 
    102     /**
    103      * Resize the layer and its texture if needed.
    104      *
    105      * @param width The new width of the layer
    106      * @param height The new height of the layer
    107      *
    108      * @return True if the layer was resized or nothing happened, false if
    109      *         a failure occurred during the resizing operation
    110      */
    111     bool resize(const uint32_t width, const uint32_t height);
    112 
    113     void setSize(uint32_t width, uint32_t height) {
    114         texture.width = width;
    115         texture.height = height;
    116     }
    117 
    118     ANDROID_API void setPaint(SkPaint* paint);
    119 
    120     inline void setBlend(bool blend) {
    121         texture.blend = blend;
    122     }
    123 
    124     inline bool isBlend() const {
    125         return texture.blend;
    126     }
    127 
    128     inline void setAlpha(int alpha) {
    129         this->alpha = alpha;
    130     }
    131 
    132     inline void setAlpha(int alpha, SkXfermode::Mode mode) {
    133         this->alpha = alpha;
    134         this->mode = mode;
    135     }
    136 
    137     inline int getAlpha() const {
    138         return alpha;
    139     }
    140 
    141     inline SkXfermode::Mode getMode() const {
    142         return mode;
    143     }
    144 
    145     inline void setEmpty(bool empty) {
    146         this->empty = empty;
    147     }
    148 
    149     inline bool isEmpty() const {
    150         return empty;
    151     }
    152 
    153     inline void setFbo(GLuint fbo) {
    154         this->fbo = fbo;
    155     }
    156 
    157     inline GLuint getFbo() const {
    158         return fbo;
    159     }
    160 
    161     inline void setStencilRenderBuffer(RenderBuffer* renderBuffer) {
    162         if (RenderBuffer::isStencilBuffer(renderBuffer->getFormat())) {
    163             this->stencil = renderBuffer;
    164             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
    165                     GL_RENDERBUFFER, stencil->getName());
    166         } else {
    167             ALOGE("The specified render buffer is not a stencil buffer");
    168         }
    169     }
    170 
    171     inline RenderBuffer* getStencilRenderBuffer() const {
    172         return stencil;
    173     }
    174 
    175     inline GLuint getTexture() const {
    176         return texture.id;
    177     }
    178 
    179     inline GLenum getRenderTarget() const {
    180         return renderTarget;
    181     }
    182 
    183     inline void setRenderTarget(GLenum renderTarget) {
    184         this->renderTarget = renderTarget;
    185     }
    186 
    187     void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
    188         texture.setWrap(wrap, bindTexture, force, renderTarget);
    189     }
    190 
    191     void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
    192         texture.setFilter(filter, bindTexture, force, renderTarget);
    193     }
    194 
    195     inline bool isCacheable() const {
    196         return cacheable;
    197     }
    198 
    199     inline void setCacheable(bool cacheable) {
    200         this->cacheable = cacheable;
    201     }
    202 
    203     inline bool isDirty() const {
    204         return dirty;
    205     }
    206 
    207     inline void setDirty(bool dirty) {
    208         this->dirty = dirty;
    209     }
    210 
    211     inline bool isTextureLayer() const {
    212         return textureLayer;
    213     }
    214 
    215     inline void setTextureLayer(bool textureLayer) {
    216         this->textureLayer = textureLayer;
    217     }
    218 
    219     inline SkiaColorFilter* getColorFilter() const {
    220         return colorFilter;
    221     }
    222 
    223     ANDROID_API void setColorFilter(SkiaColorFilter* filter);
    224 
    225     void bindStencilRenderBuffer() const;
    226 
    227     void bindTexture() const;
    228     void generateTexture();
    229     void allocateTexture();
    230     void deleteTexture();
    231 
    232     /**
    233      * When the caller frees the texture itself, the caller
    234      * must call this method to tell this layer that it lost
    235      * the texture.
    236      */
    237     ANDROID_API void clearTexture();
    238 
    239     inline mat4& getTexTransform() {
    240         return texTransform;
    241     }
    242 
    243     inline mat4& getTransform() {
    244         return transform;
    245     }
    246 
    247     void defer();
    248     void cancelDefer();
    249     void flush();
    250     void render();
    251 
    252     /**
    253      * Bounds of the layer.
    254      */
    255     Rect layer;
    256     /**
    257      * Texture coordinates of the layer.
    258      */
    259     Rect texCoords;
    260     /**
    261      * Clipping rectangle.
    262      */
    263     Rect clipRect;
    264 
    265     /**
    266      * Dirty region indicating what parts of the layer
    267      * have been drawn.
    268      */
    269     Region region;
    270     /**
    271      * If the region is a rectangle, coordinates of the
    272      * region are stored here.
    273      */
    274     Rect regionRect;
    275 
    276     /**
    277      * If the layer can be rendered as a mesh, this is non-null.
    278      */
    279     TextureVertex* mesh;
    280     GLsizei meshElementCount;
    281 
    282     /**
    283      * Used for deferred updates.
    284      */
    285     bool deferredUpdateScheduled;
    286     OpenGLRenderer* renderer;
    287     DisplayList* displayList;
    288     Rect dirtyRect;
    289     bool debugDrawUpdate;
    290     bool hasDrawnSinceUpdate;
    291 
    292 private:
    293     Caches& caches;
    294 
    295     /**
    296      * Name of the FBO used to render the layer. If the name is 0
    297      * this layer is not backed by an FBO, but a simple texture.
    298      */
    299     GLuint fbo;
    300 
    301     /**
    302      * The render buffer used as the stencil buffer.
    303      */
    304     RenderBuffer* stencil;
    305 
    306     /**
    307      * Indicates whether this layer has been used already.
    308      */
    309     bool empty;
    310 
    311     /**
    312      * The texture backing this layer.
    313      */
    314     Texture texture;
    315 
    316     /**
    317      * If set to true (by default), the layer can be reused.
    318      */
    319     bool cacheable;
    320 
    321     /**
    322      * When set to true, this layer must be treated as a texture
    323      * layer.
    324      */
    325     bool textureLayer;
    326 
    327     /**
    328      * When set to true, this layer is dirty and should be cleared
    329      * before any rendering occurs.
    330      */
    331     bool dirty;
    332 
    333     /**
    334      * Indicates the render target.
    335      */
    336     GLenum renderTarget;
    337 
    338     /**
    339      * Color filter used to draw this layer. Optional.
    340      */
    341     SkiaColorFilter* colorFilter;
    342 
    343     /**
    344      * Opacity of the layer.
    345      */
    346     int alpha;
    347     /**
    348      * Blending mode of the layer.
    349      */
    350     SkXfermode::Mode mode;
    351 
    352     /**
    353      * Optional texture coordinates transform.
    354      */
    355     mat4 texTransform;
    356 
    357     /**
    358      * Optional transform.
    359      */
    360     mat4 transform;
    361 
    362     /**
    363      * Used to defer display lists when the layer is updated with a
    364      * display list.
    365      */
    366     DeferredDisplayList* deferredList;
    367 
    368 }; // struct Layer
    369 
    370 }; // namespace uirenderer
    371 }; // namespace android
    372 
    373 #endif // ANDROID_HWUI_LAYER_H
    374