• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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          */
getMergeId()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 
Entry(SkPixelRef * pixelRef,Texture * texture,const UvMapper & mapper,const AssetAtlas & atlas)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 
~Entry()93         ~Entry() {
94             delete texture;
95         }
96 
97         friend class AssetAtlas;
98     };
99 
AssetAtlas()100     AssetAtlas(): mTexture(nullptr), mImage(nullptr),
101             mBlendKey(true), mOpaqueKey(false) { }
~AssetAtlas()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      */
getWidth()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      */
getHeight()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      */
getTexture()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