summaryrefslogtreecommitdiff
path: root/libs/hwui/PatchCache.h
diff options
context:
space:
mode:
author Romain Guy <romainguy@google.com> 2013-06-26 15:45:41 -0700
committer Romain Guy <romainguy@google.com> 2013-06-26 17:15:08 -0700
commite3b0a0117a2ab4118f868a731b238fe8f2430276 (patch)
treea4a6ac3783ace541cd35a0f9d3868af6d2bf97b7 /libs/hwui/PatchCache.h
parent89dc02a9bed818cc6f5296c97eb504ccb010db42 (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.h55
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