1 /* 2 * Copyright (C) 2010 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_PATCH_CACHE_H 18 #define ANDROID_HWUI_PATCH_CACHE_H 19 20 #include <GLES2/gl2.h> 21 22 #include <utils/LruCache.h> 23 24 #include <androidfw/ResourceTypes.h> 25 26 #include "AssetAtlas.h" 27 #include "Debug.h" 28 #include "Patch.h" 29 #include "utils/Pair.h" 30 31 namespace android { 32 namespace uirenderer { 33 34 /////////////////////////////////////////////////////////////////////////////// 35 // Defines 36 /////////////////////////////////////////////////////////////////////////////// 37 38 // Debug 39 #if DEBUG_PATCHES 40 #define PATCH_LOGD(...) ALOGD(__VA_ARGS__) 41 #else 42 #define PATCH_LOGD(...) 43 #endif 44 45 /////////////////////////////////////////////////////////////////////////////// 46 // Cache 47 /////////////////////////////////////////////////////////////////////////////// 48 49 class Caches; 50 51 class PatchCache { 52 public: 53 PatchCache(); 54 ~PatchCache(); 55 void init(Caches& caches); 56 57 const Patch* get(const AssetAtlas::Entry* entry, 58 const uint32_t bitmapWidth, const uint32_t bitmapHeight, 59 const float pixelWidth, const float pixelHeight, const Res_png_9patch* patch); 60 void clear(); 61 62 uint32_t getSize() const { 63 return mSize; 64 } 65 66 uint32_t getMaxSize() const { 67 return mMaxSize; 68 } 69 70 GLuint getMeshBuffer() const { 71 return mMeshBuffer; 72 } 73 74 uint32_t getGenerationId() const { 75 return mGenerationId; 76 } 77 78 /** 79 * Removes the entries associated with the specified 9-patch. This is meant 80 * to be called from threads that are not the EGL context thread (GC thread 81 * on the VM side for instance.) 82 */ 83 void removeDeferred(Res_png_9patch* patch); 84 85 /** 86 * Process deferred removals. 87 */ 88 void clearGarbage(); 89 90 91 private: 92 struct PatchDescription { 93 PatchDescription(): mPatch(NULL), mBitmapWidth(0), mBitmapHeight(0), 94 mPixelWidth(0), mPixelHeight(0) { 95 } 96 97 PatchDescription(const uint32_t bitmapWidth, const uint32_t bitmapHeight, 98 const float pixelWidth, const float pixelHeight, const Res_png_9patch* patch): 99 mPatch(patch), mBitmapWidth(bitmapWidth), mBitmapHeight(bitmapHeight), 100 mPixelWidth(pixelWidth), mPixelHeight(pixelHeight) { 101 } 102 103 hash_t hash() const; 104 105 const Res_png_9patch* getPatch() const { return mPatch; } 106 107 static int compare(const PatchDescription& lhs, const PatchDescription& rhs); 108 109 bool operator==(const PatchDescription& other) const { 110 return compare(*this, other) == 0; 111 } 112 113 bool operator!=(const PatchDescription& other) const { 114 return compare(*this, other) != 0; 115 } 116 117 friend inline int strictly_order_type(const PatchDescription& lhs, 118 const PatchDescription& rhs) { 119 return PatchDescription::compare(lhs, rhs) < 0; 120 } 121 122 friend inline int compare_type(const PatchDescription& lhs, 123 const PatchDescription& rhs) { 124 return PatchDescription::compare(lhs, rhs); 125 } 126 127 friend inline hash_t hash_type(const PatchDescription& entry) { 128 return entry.hash(); 129 } 130 131 private: 132 const Res_png_9patch* mPatch; 133 uint32_t mBitmapWidth; 134 uint32_t mBitmapHeight; 135 float mPixelWidth; 136 float mPixelHeight; 137 138 }; // struct PatchDescription 139 140 /** 141 * A buffer block represents an empty range in the mesh buffer 142 * that can be used to store vertices. 143 * 144 * The patch cache maintains a linked-list of buffer blocks 145 * to track available regions of memory in the VBO. 146 */ 147 struct BufferBlock { 148 BufferBlock(uint32_t offset, uint32_t size): offset(offset), size(size), next(NULL) { 149 } 150 151 uint32_t offset; 152 uint32_t size; 153 154 BufferBlock* next; 155 }; // struct BufferBlock 156 157 typedef Pair<const PatchDescription*, Patch*> patch_pair_t; 158 159 void clearCache(); 160 void createVertexBuffer(); 161 162 void setupMesh(Patch* newMesh, TextureVertex* vertices); 163 164 void remove(Vector<patch_pair_t>& patchesToRemove, Res_png_9patch* patch); 165 166 #if DEBUG_PATCHES 167 void dumpFreeBlocks(const char* prefix); 168 #endif 169 170 uint32_t mMaxSize; 171 uint32_t mSize; 172 173 LruCache<PatchDescription, Patch*> mCache; 174 175 GLuint mMeshBuffer; 176 // First available free block inside the mesh buffer 177 BufferBlock* mFreeBlocks; 178 179 uint32_t mGenerationId; 180 181 // Garbage tracking, required to handle GC events on the VM side 182 Vector<Res_png_9patch*> mGarbage; 183 mutable Mutex mLock; 184 }; // class PatchCache 185 186 }; // namespace uirenderer 187 }; // namespace android 188 189 #endif // ANDROID_HWUI_PATCH_CACHE_H 190