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