PatchCache.h revision 5e00c7ce063116c11315639f0035aca8ad73e8cc
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 "AssetAtlas.h"
26#include "Debug.h"
27#include "utils/Pair.h"
28
29namespace android {
30namespace uirenderer {
31
32class Patch;
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
49class Caches;
50class RenderState;
51
52class PatchCache {
53public:
54    PatchCache(RenderState& renderState);
55    ~PatchCache();
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
91private:
92    struct PatchDescription {
93        PatchDescription(): mPatch(nullptr), 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(nullptr) {
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);
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    RenderState& mRenderState;
171    const uint32_t mMaxSize;
172    uint32_t mSize;
173
174    LruCache<PatchDescription, Patch*> mCache;
175
176    GLuint mMeshBuffer;
177    // First available free block inside the mesh buffer
178    BufferBlock* mFreeBlocks;
179
180    uint32_t mGenerationId;
181
182    // Garbage tracking, required to handle GC events on the VM side
183    Vector<Res_png_9patch*> mGarbage;
184    mutable Mutex mLock;
185}; // class PatchCache
186
187}; // namespace uirenderer
188}; // namespace android
189