• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getSize()62     uint32_t getSize() const {
63         return mSize;
64     }
65 
getMaxSize()66     uint32_t getMaxSize() const {
67         return mMaxSize;
68     }
69 
getMeshBuffer()70     GLuint getMeshBuffer() const {
71         return mMeshBuffer;
72     }
73 
getGenerationId()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 {
PatchDescriptionPatchDescription93         PatchDescription(): mPatch(NULL), mBitmapWidth(0), mBitmapHeight(0),
94                 mPixelWidth(0), mPixelHeight(0) {
95         }
96 
PatchDescriptionPatchDescription97         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 
getPatchPatchDescription105         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 
strictly_order_typePatchDescription117         friend inline int strictly_order_type(const PatchDescription& lhs,
118                 const PatchDescription& rhs) {
119             return PatchDescription::compare(lhs, rhs) < 0;
120         }
121 
compare_typePatchDescription122         friend inline int compare_type(const PatchDescription& lhs,
123                 const PatchDescription& rhs) {
124             return PatchDescription::compare(lhs, rhs);
125         }
126 
hash_typePatchDescription127         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 {
BufferBlockBufferBlock148         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