diff options
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 |
commit | e3b0a0117a2ab4118f868a731b238fe8f2430276 (patch) | |
tree | a4a6ac3783ace541cd35a0f9d3868af6d2bf97b7 /libs/hwui/ResourceCache.cpp | |
parent | 89dc02a9bed818cc6f5296c97eb504ccb010db42 (diff) | |
download | frameworks_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.cpp | 52 |
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); |