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