summaryrefslogtreecommitdiffstats
path: root/libs/hwui/ResourceCache.cpp
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2013-06-26 15:45:41 -0700
committerRomain Guy <romainguy@google.com>2013-06-26 17:15:08 -0700
commite3b0a0117a2ab4118f868a731b238fe8f2430276 (patch)
treea4a6ac3783ace541cd35a0f9d3868af6d2bf97b7 /libs/hwui/ResourceCache.cpp
parent89dc02a9bed818cc6f5296c97eb504ccb010db42 (diff)
downloadframeworks_base-e3b0a0117a2ab4118f868a731b238fe8f2430276.zip
frameworks_base-e3b0a0117a2ab4118f868a731b238fe8f2430276.tar.gz
frameworks_base-e3b0a0117a2ab4118f868a731b238fe8f2430276.tar.bz2
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/ResourceCache.cpp')
-rw-r--r--libs/hwui/ResourceCache.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index 347bd78..58fa21c 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define LOG_TAG "OpenGLRenderer"
+
#include <SkPixelRef.h>
#include "ResourceCache.h"
#include "Caches.h"
@@ -79,6 +81,10 @@ void ResourceCache::incrementRefcount(SkiaColorFilter* filterResource) {
incrementRefcount((void*) filterResource, kColorFilter);
}
+void ResourceCache::incrementRefcount(Res_png_9patch* patchResource) {
+ incrementRefcount((void*) patchResource, kNinePatch);
+}
+
void ResourceCache::incrementRefcount(Layer* layerResource) {
incrementRefcount((void*) layerResource, kLayer);
}
@@ -113,6 +119,10 @@ void ResourceCache::incrementRefcountLocked(SkiaColorFilter* filterResource) {
incrementRefcountLocked((void*) filterResource, kColorFilter);
}
+void ResourceCache::incrementRefcountLocked(Res_png_9patch* patchResource) {
+ incrementRefcountLocked((void*) patchResource, kNinePatch);
+}
+
void ResourceCache::incrementRefcountLocked(Layer* layerResource) {
incrementRefcountLocked((void*) layerResource, kLayer);
}
@@ -142,6 +152,10 @@ void ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) {
decrementRefcount((void*) filterResource);
}
+void ResourceCache::decrementRefcount(Res_png_9patch* patchResource) {
+ decrementRefcount((void*) patchResource);
+}
+
void ResourceCache::decrementRefcount(Layer* layerResource) {
decrementRefcount((void*) layerResource);
}
@@ -179,6 +193,10 @@ void ResourceCache::decrementRefcountLocked(SkiaColorFilter* filterResource) {
decrementRefcountLocked((void*) filterResource);
}
+void ResourceCache::decrementRefcountLocked(Res_png_9patch* patchResource) {
+ decrementRefcountLocked((void*) patchResource);
+}
+
void ResourceCache::decrementRefcountLocked(Layer* layerResource) {
decrementRefcountLocked((void*) layerResource);
}
@@ -265,6 +283,30 @@ void ResourceCache::destructorLocked(SkiaColorFilter* resource) {
}
}
+void ResourceCache::destructor(Res_png_9patch* resource) {
+ Mutex::Autolock _l(mLock);
+ destructorLocked(resource);
+}
+
+void ResourceCache::destructorLocked(Res_png_9patch* resource) {
+ ssize_t index = mCache->indexOfKey(resource);
+ ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
+ if (ref == NULL) {
+ if (Caches::hasInstance()) {
+ Caches::getInstance().patchCache.removeDeferred(resource);
+ }
+ // If we're not tracking this resource, just delete it
+ // A Res_png_9patch is actually an array of byte that's larger
+ // than sizeof(Res_png_9patch). It must be freed as an array.
+ delete[] (int8_t*) resource;
+ return;
+ }
+ ref->destroyed = true;
+ if (ref->refCount == 0) {
+ deleteResourceReferenceLocked(resource, ref);
+ }
+}
+
/**
* Return value indicates whether resource was actually recycled, which happens when RefCnt
* reaches 0.
@@ -335,6 +377,16 @@ void ResourceCache::deleteResourceReferenceLocked(void* resource, ResourceRefere
delete filter;
}
break;
+ case kNinePatch: {
+ if (Caches::hasInstance()) {
+ Caches::getInstance().patchCache.removeDeferred((Res_png_9patch*) resource);
+ }
+ // A Res_png_9patch is actually an array of byte that's larger
+ // than sizeof(Res_png_9patch). It must be freed as an array.
+ int8_t* patch = (int8_t*) resource;
+ delete[] patch;
+ }
+ break;
case kLayer: {
Layer* layer = (Layer*) resource;
Caches::getInstance().deleteLayerDeferred(layer);