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