PatchCache.h revision 48a8f431fa52ae2ee25ffba9d20676f03bb710ff
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
30namespace android {
31namespace uirenderer {
32
33class 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
50class Caches;
51
52class PatchCache {
53public:
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
63    uint32_t getSize() const {
64        return mSize;
65    }
66
67    uint32_t getMaxSize() const {
68        return mMaxSize;
69    }
70
71    GLuint getMeshBuffer() const {
72        return mMeshBuffer;
73    }
74
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
92private:
93    struct PatchDescription {
94        PatchDescription(): mPatch(nullptr), mBitmapWidth(0), mBitmapHeight(0),
95                mPixelWidth(0), mPixelHeight(0) {
96        }
97
98        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
106        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
118        friend inline int strictly_order_type(const PatchDescription& lhs,
119                const PatchDescription& rhs) {
120            return PatchDescription::compare(lhs, rhs) < 0;
121        }
122
123        friend inline int compare_type(const PatchDescription& lhs,
124                const PatchDescription& rhs) {
125            return PatchDescription::compare(lhs, rhs);
126        }
127
128        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 {
149        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