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