• 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 "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          */
getMergeIdEntry91         const void* getMergeId() const {
92             return texture->blend ? &atlas.mBlendKey : &atlas.mOpaqueKey;
93         }
94 
95     private:
EntryEntry96         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 
~EntryEntry102         ~Entry() {
103             delete texture;
104         }
105 
106         friend class AssetAtlas;
107     };
108 
AssetAtlas()109     AssetAtlas(): mTexture(NULL), mImage(NULL),
110             mBlendKey(true), mOpaqueKey(false) { }
~AssetAtlas()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, int64_t* 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     void terminate();
134 
135     /**
136      * Returns the width of this atlas in pixels.
137      * Can return 0 if the atlas is not initialized.
138      */
getWidth()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      */
getHeight()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      */
getTexture()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(const SkBitmap* 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(const SkBitmap* bitmap) const;
170 
171 private:
172     void createEntries(Caches& caches, int64_t* map, int count);
173     void updateTextureId();
174 
175     Texture* mTexture;
176     Image* mImage;
177 
178     const bool mBlendKey;
179     const bool mOpaqueKey;
180 
181     KeyedVector<const SkBitmap*, Entry*> mEntries;
182 }; // class AssetAtlas
183 
184 }; // namespace uirenderer
185 }; // namespace android
186 
187 #endif // ANDROID_HWUI_ASSET_ATLAS_H
188