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