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 "Texture.h"
     31 #include "UvMapper.h"
     32 
     33 namespace android {
     34 namespace uirenderer {
     35 
     36 class Caches;
     37 class Image;
     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 texture and uvMapper of a PixelRef in the
     49      * atlas
     50      */
     51     class Entry {
     52     public:
     53         /*
     54          * A "virtual texture" object that represents the texture
     55          * this entry belongs to. This texture should never be
     56          * modified.
     57          */
     58         Texture* texture;
     59 
     60         /**
     61          * Maps texture coordinates in the [0..1] range into the
     62          * correct range to sample this entry from the atlas.
     63          */
     64         const UvMapper uvMapper;
     65 
     66         /**
     67          * Unique identifier used to merge bitmaps and 9-patches stored
     68          * in the atlas.
     69          */
     70         const void* getMergeId() const {
     71             return texture->blend ? &atlas.mBlendKey : &atlas.mOpaqueKey;
     72         }
     73 
     74     private:
     75         /**
     76          * The pixel ref that generated this atlas entry.
     77          */
     78         SkPixelRef* pixelRef;
     79 
     80         /**
     81          * Atlas this entry belongs to.
     82          */
     83         const AssetAtlas& atlas;
     84 
     85         Entry(SkPixelRef* pixelRef, Texture* texture, const UvMapper& mapper,
     86                     const AssetAtlas& atlas)
     87                 : texture(texture)
     88                 , uvMapper(mapper)
     89                 , pixelRef(pixelRef)
     90                 , atlas(atlas) {
     91         }
     92 
     93         ~Entry() {
     94             delete texture;
     95         }
     96 
     97         friend class AssetAtlas;
     98     };
     99 
    100     AssetAtlas(): mTexture(nullptr), mImage(nullptr),
    101             mBlendKey(true), mOpaqueKey(false) { }
    102     ~AssetAtlas() { terminate(); }
    103 
    104     /**
    105      * Initializes the atlas with the specified buffer and
    106      * map. The buffer is a gralloc'd texture that will be
    107      * used as an EGLImage. The map is a list of SkBitmap*
    108      * and their (x, y) positions
    109      *
    110      * This method returns immediately if the atlas is already
    111      * initialized. To re-initialize the atlas, you must
    112      * first call terminate().
    113      */
    114     ANDROID_API void init(sp<GraphicBuffer> buffer, int64_t* map, int count);
    115 
    116     /**
    117      * Destroys the atlas texture. This object can be
    118      * re-initialized after calling this method.
    119      *
    120      * After calling this method, the width, height
    121      * and texture are set to 0.
    122      */
    123     void terminate();
    124 
    125     /**
    126      * Returns the width of this atlas in pixels.
    127      * Can return 0 if the atlas is not initialized.
    128      */
    129     uint32_t getWidth() const {
    130         return mTexture ? mTexture->width : 0;
    131     }
    132 
    133     /**
    134      * Returns the height of this atlas in pixels.
    135      * Can return 0 if the atlas is not initialized.
    136      */
    137     uint32_t getHeight() const {
    138         return mTexture ? mTexture->height : 0;
    139     }
    140 
    141     /**
    142      * Returns the OpenGL name of the texture backing this atlas.
    143      * Can return 0 if the atlas is not initialized.
    144      */
    145     GLuint getTexture() const {
    146         return mTexture ? mTexture->id : 0;
    147     }
    148 
    149     /**
    150      * Returns the entry in the atlas associated with the specified
    151      * bitmap. If the bitmap is not in the atlas, return NULL.
    152      */
    153     Entry* getEntry(const SkBitmap* bitmap) const;
    154 
    155     /**
    156      * Returns the texture for the atlas entry associated with the
    157      * specified bitmap. If the bitmap is not in the atlas, return NULL.
    158      */
    159     Texture* getEntryTexture(const SkBitmap* bitmap) const;
    160 
    161 private:
    162     void createEntries(Caches& caches, int64_t* map, int count);
    163     void updateTextureId();
    164 
    165     Texture* mTexture;
    166     Image* mImage;
    167 
    168     const bool mBlendKey;
    169     const bool mOpaqueKey;
    170 
    171     KeyedVector<const SkPixelRef*, Entry*> mEntries;
    172 }; // class AssetAtlas
    173 
    174 }; // namespace uirenderer
    175 }; // namespace android
    176 
    177 #endif // ANDROID_HWUI_ASSET_ATLAS_H
    178