Home | History | Annotate | Download | only in hwui
      1 /*
      2  * Copyright (C) 2013 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_ASSET_ATLAS_H
     18 #define ANDROID_HWUI_ASSET_ATLAS_H
     19 
     20 #include <GLES2/gl2.h>
     21 
     22 #include <ui/GraphicBuffer.h>
     23 
     24 #include <utils/KeyedVector.h>
     25 
     26 #include <cutils/compiler.h>
     27 
     28 #include <SkBitmap.h>
     29 
     30 #include "Image.h"
     31 #include "Texture.h"
     32 #include "UvMapper.h"
     33 
     34 namespace android {
     35 namespace uirenderer {
     36 
     37 class Caches;
     38 
     39 /**
     40  * An asset atlas holds a collection of framework bitmaps in a single OpenGL
     41  * texture. Each bitmap is associated with a location, defined in pixels,
     42  * inside the atlas. The atlas is generated by the framework and bound as
     43  * an external texture using the EGLImageKHR extension.
     44  */
     45 class AssetAtlas {
     46 public:
     47     /**
     48      * Entry representing the position and rotation of a
     49      * bitmap inside the atlas.
     50      */
     51     struct Entry {
     52         /**
     53          * The bitmap that generated this atlas entry.
     54          */
     55         SkBitmap* bitmap;
     56 
     57         /**
     58          * Location of the bitmap inside the atlas, in pixels.
     59          */
     60         int x;
     61         int y;
     62 
     63         /**
     64          * If set, the bitmap is rotated 90 degrees (clockwise)
     65          * inside the atlas.
     66          */
     67         bool rotated;
     68 
     69         /*
     70          * A "virtual texture" object that represents the texture
     71          * this entry belongs to. This texture should never be
     72          * modified.
     73          */
     74         Texture* texture;
     75 
     76         /**
     77          * Maps texture coordinates in the [0..1] range into the
     78          * correct range to sample this entry from the atlas.
     79          */
     80         const UvMapper uvMapper;
     81 
     82         /**
     83          * Atlas this entry belongs to.
     84          */
     85         const AssetAtlas& atlas;
     86 
     87         /**
     88          * Unique identifier used to merge bitmaps and 9-patches stored
     89          * in the atlas.
     90          */
     91         const void* getMergeId() const {
     92             return texture->blend ? &atlas.mBlendKey : &atlas.mOpaqueKey;
     93         }
     94 
     95     private:
     96         Entry(SkBitmap* bitmap, int x, int y, bool rotated,
     97                 Texture* texture, const UvMapper& mapper, const AssetAtlas& atlas):
     98                 bitmap(bitmap), x(x), y(y), rotated(rotated),
     99                 texture(texture), uvMapper(mapper), atlas(atlas) {
    100         }
    101 
    102         ~Entry() {
    103             delete texture;
    104         }
    105 
    106         friend class AssetAtlas;
    107     };
    108 
    109     AssetAtlas(): mTexture(NULL), mImage(NULL), mGenerationId(0),
    110             mBlendKey(true), mOpaqueKey(false) { }
    111     ~AssetAtlas() { terminate(); }
    112 
    113     /**
    114      * Initializes the atlas with the specified buffer and
    115      * map. The buffer is a gralloc'd texture that will be
    116      * used as an EGLImage. The map is a list of SkBitmap*
    117      * and their (x, y) positions as well as their rotation
    118      * flags.
    119      *
    120      * This method returns immediately if the atlas is already
    121      * initialized. To re-initialize the atlas, you must
    122      * first call terminate().
    123      */
    124     ANDROID_API void init(sp<GraphicBuffer> buffer, int* map, int count);
    125 
    126     /**
    127      * Destroys the atlas texture. This object can be
    128      * re-initialized after calling this method.
    129      *
    130      * After calling this method, the width, height
    131      * and texture are set to 0.
    132      */
    133     ANDROID_API void terminate();
    134 
    135     /**
    136      * Returns the width of this atlas in pixels.
    137      * Can return 0 if the atlas is not initialized.
    138      */
    139     uint32_t getWidth() const {
    140         return mTexture ? mTexture->width : 0;
    141     }
    142 
    143     /**
    144      * Returns the height of this atlas in pixels.
    145      * Can return 0 if the atlas is not initialized.
    146      */
    147     uint32_t getHeight() const {
    148         return mTexture ? mTexture->height : 0;
    149     }
    150 
    151     /**
    152      * Returns the OpenGL name of the texture backing this atlas.
    153      * Can return 0 if the atlas is not initialized.
    154      */
    155     GLuint getTexture() const {
    156         return mTexture ? mTexture->id : 0;
    157     }
    158 
    159     /**
    160      * Returns the entry in the atlas associated with the specified
    161      * bitmap. If the bitmap is not in the atlas, return NULL.
    162      */
    163     Entry* getEntry(SkBitmap* const bitmap) const;
    164 
    165     /**
    166      * Returns the texture for the atlas entry associated with the
    167      * specified bitmap. If the bitmap is not in the atlas, return NULL.
    168      */
    169     Texture* getEntryTexture(SkBitmap* const bitmap) const;
    170 
    171     /**
    172      * Returns the current generation id of the atlas.
    173      */
    174     uint32_t getGenerationId() const {
    175         return mGenerationId;
    176     }
    177 
    178 private:
    179     void createEntries(Caches& caches, int* map, int count);
    180 
    181     Texture* mTexture;
    182     Image* mImage;
    183 
    184     uint32_t mGenerationId;
    185 
    186     const bool mBlendKey;
    187     const bool mOpaqueKey;
    188 
    189     KeyedVector<SkBitmap*, Entry*> mEntries;
    190 }; // class AssetAtlas
    191 
    192 }; // namespace uirenderer
    193 }; // namespace android
    194 
    195 #endif // ANDROID_HWUI_ASSET_ATLAS_H
    196