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