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