diff options
| author | 2013-06-26 15:45:41 -0700 | |
|---|---|---|
| committer | 2013-06-26 17:15:08 -0700 | |
| commit | e3b0a0117a2ab4118f868a731b238fe8f2430276 (patch) | |
| tree | a4a6ac3783ace541cd35a0f9d3868af6d2bf97b7 /libs/hwui/PatchCache.h | |
| parent | 89dc02a9bed818cc6f5296c97eb504ccb010db42 (diff) | |
Refcount 9-patches and properly handle GC events
This change adds refcounting of Res_png_9patch instances, the native
data structure used to represent 9-patches. The Dalvik NinePatch class
now holds a native pointer instead of a Dalvik byte[]. This pointer
is used whenever we need to draw the 9-patch (software or hardware.)
Since we are now tracking garbage collection of NinePatch objects
libhwui's PatchCache must keep a list of free blocks in the VBO
used to store the meshes.
This change also removes unnecessary instances tracking from
GLES20DisplayList. Bitmaps and 9-patches are refcounted at the
native level and do not need to be tracked by the Dalvik layer.
Change-Id: Ib8682d573a538aaf1945f8ec5a9bd5da5d16f74b
Diffstat (limited to 'libs/hwui/PatchCache.h')
| -rw-r--r-- | libs/hwui/PatchCache.h | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/libs/hwui/PatchCache.h b/libs/hwui/PatchCache.h index 1829b89dbfc0..9f2c9a59387b 100644 --- a/libs/hwui/PatchCache.h +++ b/libs/hwui/PatchCache.h @@ -26,6 +26,7 @@ #include "AssetAtlas.h" #include "Debug.h" #include "Patch.h" +#include "utils/Pair.h" namespace android { namespace uirenderer { @@ -74,10 +75,20 @@ public: return mGenerationId; } -private: - void clearCache(); - void createVertexBuffer(); + /** + * Removes the entries associated with the specified 9-patch. This is meant + * to be called from threads that are not the EGL context thread (GC thread + * on the VM side for instance.) + */ + void removeDeferred(Res_png_9patch* patch); + /** + * Process deferred removals. + */ + void clearGarbage(); + + +private: struct PatchDescription { PatchDescription(): mPatch(NULL), mBitmapWidth(0), mBitmapHeight(0), mPixelWidth(0), mPixelHeight(0) { @@ -91,6 +102,8 @@ private: hash_t hash() const; + const Res_png_9patch* getPatch() const { return mPatch; } + static int compare(const PatchDescription& lhs, const PatchDescription& rhs); bool operator==(const PatchDescription& other) const { @@ -124,14 +137,50 @@ private: }; // struct PatchDescription + /** + * A buffer block represents an empty range in the mesh buffer + * that can be used to store vertices. + * + * The patch cache maintains a linked-list of buffer blocks + * to track available regions of memory in the VBO. + */ + struct BufferBlock { + BufferBlock(uint32_t offset, uint32_t size): offset(offset), size(size), next(NULL) { + } + + uint32_t offset; + uint32_t size; + + BufferBlock* next; + }; // struct BufferBlock + + typedef Pair<const PatchDescription*, Patch*> patch_pair_t; + + void clearCache(); + void createVertexBuffer(); + + void setupMesh(Patch* newMesh, TextureVertex* vertices); + + void remove(Vector<patch_pair_t>& patchesToRemove, Res_png_9patch* patch); + +#if DEBUG_PATCHES + void dumpFreeBlocks(const char* prefix); +#endif + uint32_t mMaxSize; uint32_t mSize; LruCache<PatchDescription, Patch*> mCache; GLuint mMeshBuffer; + // First available free block inside the mesh buffer + BufferBlock* mFreeBlocks; uint32_t mGenerationId; + + // Garbage tracking, required to handle GC events on the VM side + Vector<Res_png_9patch*> mGarbage; + mutable Mutex mLock; }; // class PatchCache }; // namespace uirenderer |