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