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