summaryrefslogtreecommitdiffstats
path: root/libs/hwui/ResourceCache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/ResourceCache.cpp')
-rw-r--r--libs/hwui/ResourceCache.cpp189
1 files changed, 152 insertions, 37 deletions
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index cf5f822..347bd78 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -38,7 +38,7 @@ void ResourceCache::logCache() {
ResourceCache::ResourceCache() {
Mutex::Autolock _l(mLock);
- mCache = new KeyedVector<void *, ResourceReference *>();
+ mCache = new KeyedVector<void*, ResourceReference*>();
}
ResourceCache::~ResourceCache() {
@@ -46,14 +46,17 @@ ResourceCache::~ResourceCache() {
delete mCache;
}
+void ResourceCache::lock() {
+ mLock.lock();
+}
+
+void ResourceCache::unlock() {
+ mLock.unlock();
+}
+
void ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) {
Mutex::Autolock _l(mLock);
- ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
- if (ref == NULL || mCache->size() == 0) {
- ref = new ResourceReference(resourceType);
- mCache->add(resource, ref);
- }
- ref->refCount++;
+ incrementRefcountLocked(resource, resourceType);
}
void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
@@ -76,17 +79,47 @@ void ResourceCache::incrementRefcount(SkiaColorFilter* filterResource) {
incrementRefcount((void*) filterResource, kColorFilter);
}
+void ResourceCache::incrementRefcount(Layer* layerResource) {
+ incrementRefcount((void*) layerResource, kLayer);
+}
+
+void ResourceCache::incrementRefcountLocked(void* resource, ResourceType resourceType) {
+ ssize_t index = mCache->indexOfKey(resource);
+ ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
+ if (ref == NULL || mCache->size() == 0) {
+ ref = new ResourceReference(resourceType);
+ mCache->add(resource, ref);
+ }
+ ref->refCount++;
+}
+
+void ResourceCache::incrementRefcountLocked(SkBitmap* bitmapResource) {
+ SkSafeRef(bitmapResource->pixelRef());
+ SkSafeRef(bitmapResource->getColorTable());
+ incrementRefcountLocked((void*) bitmapResource, kBitmap);
+}
+
+void ResourceCache::incrementRefcountLocked(SkPath* pathResource) {
+ incrementRefcountLocked((void*) pathResource, kPath);
+}
+
+void ResourceCache::incrementRefcountLocked(SkiaShader* shaderResource) {
+ SkSafeRef(shaderResource->getSkShader());
+ incrementRefcountLocked((void*) shaderResource, kShader);
+}
+
+void ResourceCache::incrementRefcountLocked(SkiaColorFilter* filterResource) {
+ SkSafeRef(filterResource->getSkColorFilter());
+ incrementRefcountLocked((void*) filterResource, kColorFilter);
+}
+
+void ResourceCache::incrementRefcountLocked(Layer* layerResource) {
+ incrementRefcountLocked((void*) layerResource, kLayer);
+}
+
void ResourceCache::decrementRefcount(void* resource) {
Mutex::Autolock _l(mLock);
- ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
- if (ref == NULL) {
- // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
- return;
- }
- ref->refCount--;
- if (ref->refCount == 0) {
- deleteResourceReference(resource, ref);
- }
+ decrementRefcountLocked(resource);
}
void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
@@ -109,27 +142,55 @@ void ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) {
decrementRefcount((void*) filterResource);
}
-void ResourceCache::recycle(SkBitmap* resource) {
- Mutex::Autolock _l(mLock);
- if (mCache->indexOfKey(resource) < 0) {
- // not tracking this resource; just recycle the pixel data
- resource->setPixels(NULL, NULL);
- return;
- }
- ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
+void ResourceCache::decrementRefcount(Layer* layerResource) {
+ decrementRefcount((void*) layerResource);
+}
+
+void ResourceCache::decrementRefcountLocked(void* resource) {
+ ssize_t index = mCache->indexOfKey(resource);
+ ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
if (ref == NULL) {
- // Should not get here - shouldn't get a call to recycle if we're not yet tracking it
+ // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
return;
}
- ref->recycled = true;
+ ref->refCount--;
if (ref->refCount == 0) {
- deleteResourceReference(resource, ref);
+ deleteResourceReferenceLocked(resource, ref);
}
}
+void ResourceCache::decrementRefcountLocked(SkBitmap* bitmapResource) {
+ SkSafeUnref(bitmapResource->pixelRef());
+ SkSafeUnref(bitmapResource->getColorTable());
+ decrementRefcountLocked((void*) bitmapResource);
+}
+
+void ResourceCache::decrementRefcountLocked(SkPath* pathResource) {
+ decrementRefcountLocked((void*) pathResource);
+}
+
+void ResourceCache::decrementRefcountLocked(SkiaShader* shaderResource) {
+ SkSafeUnref(shaderResource->getSkShader());
+ decrementRefcountLocked((void*) shaderResource);
+}
+
+void ResourceCache::decrementRefcountLocked(SkiaColorFilter* filterResource) {
+ SkSafeUnref(filterResource->getSkColorFilter());
+ decrementRefcountLocked((void*) filterResource);
+}
+
+void ResourceCache::decrementRefcountLocked(Layer* layerResource) {
+ decrementRefcountLocked((void*) layerResource);
+}
+
void ResourceCache::destructor(SkPath* resource) {
Mutex::Autolock _l(mLock);
- ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
+ destructorLocked(resource);
+}
+
+void ResourceCache::destructorLocked(SkPath* resource) {
+ ssize_t index = mCache->indexOfKey(resource);
+ ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
if (ref == NULL) {
// If we're not tracking this resource, just delete it
if (Caches::hasInstance()) {
@@ -140,13 +201,18 @@ void ResourceCache::destructor(SkPath* resource) {
}
ref->destroyed = true;
if (ref->refCount == 0) {
- deleteResourceReference(resource, ref);
+ deleteResourceReferenceLocked(resource, ref);
}
}
void ResourceCache::destructor(SkBitmap* resource) {
Mutex::Autolock _l(mLock);
- ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
+ destructorLocked(resource);
+}
+
+void ResourceCache::destructorLocked(SkBitmap* resource) {
+ ssize_t index = mCache->indexOfKey(resource);
+ ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
if (ref == NULL) {
// If we're not tracking this resource, just delete it
if (Caches::hasInstance()) {
@@ -157,13 +223,18 @@ void ResourceCache::destructor(SkBitmap* resource) {
}
ref->destroyed = true;
if (ref->refCount == 0) {
- deleteResourceReference(resource, ref);
+ deleteResourceReferenceLocked(resource, ref);
}
}
void ResourceCache::destructor(SkiaShader* resource) {
Mutex::Autolock _l(mLock);
- ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
+ destructorLocked(resource);
+}
+
+void ResourceCache::destructorLocked(SkiaShader* resource) {
+ ssize_t index = mCache->indexOfKey(resource);
+ ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
if (ref == NULL) {
// If we're not tracking this resource, just delete it
delete resource;
@@ -171,13 +242,18 @@ void ResourceCache::destructor(SkiaShader* resource) {
}
ref->destroyed = true;
if (ref->refCount == 0) {
- deleteResourceReference(resource, ref);
+ deleteResourceReferenceLocked(resource, ref);
}
}
void ResourceCache::destructor(SkiaColorFilter* resource) {
Mutex::Autolock _l(mLock);
- ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
+ destructorLocked(resource);
+}
+
+void ResourceCache::destructorLocked(SkiaColorFilter* resource) {
+ ssize_t index = mCache->indexOfKey(resource);
+ ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
if (ref == NULL) {
// If we're not tracking this resource, just delete it
delete resource;
@@ -185,19 +261,53 @@ void ResourceCache::destructor(SkiaColorFilter* resource) {
}
ref->destroyed = true;
if (ref->refCount == 0) {
- deleteResourceReference(resource, ref);
+ deleteResourceReferenceLocked(resource, ref);
}
}
/**
+ * Return value indicates whether resource was actually recycled, which happens when RefCnt
+ * reaches 0.
+ */
+bool ResourceCache::recycle(SkBitmap* resource) {
+ Mutex::Autolock _l(mLock);
+ return recycleLocked(resource);
+}
+
+/**
+ * Return value indicates whether resource was actually recycled, which happens when RefCnt
+ * reaches 0.
+ */
+bool ResourceCache::recycleLocked(SkBitmap* resource) {
+ ssize_t index = mCache->indexOfKey(resource);
+ if (index < 0) {
+ // not tracking this resource; just recycle the pixel data
+ resource->setPixels(NULL, NULL);
+ return true;
+ }
+ ResourceReference* ref = mCache->valueAt(index);
+ if (ref == NULL) {
+ // Should not get here - shouldn't get a call to recycle if we're not yet tracking it
+ return true;
+ }
+ ref->recycled = true;
+ if (ref->refCount == 0) {
+ deleteResourceReferenceLocked(resource, ref);
+ return true;
+ }
+ // Still referring to resource, don't recycle yet
+ return false;
+}
+
+/**
* This method should only be called while the mLock mutex is held (that mutex is grabbed
* by the various destructor() and recycle() methods which call this method).
*/
-void ResourceCache::deleteResourceReference(void* resource, ResourceReference* ref) {
+void ResourceCache::deleteResourceReferenceLocked(void* resource, ResourceReference* ref) {
if (ref->recycled && ref->resourceType == kBitmap) {
((SkBitmap*) resource)->setPixels(NULL, NULL);
}
- if (ref->destroyed) {
+ if (ref->destroyed || ref->resourceType == kLayer) {
switch (ref->resourceType) {
case kBitmap: {
SkBitmap* bitmap = (SkBitmap*) resource;
@@ -225,6 +335,11 @@ void ResourceCache::deleteResourceReference(void* resource, ResourceReference* r
delete filter;
}
break;
+ case kLayer: {
+ Layer* layer = (Layer*) resource;
+ Caches::getInstance().deleteLayerDeferred(layer);
+ }
+ break;
}
}
mCache->removeItem(resource);