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