summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorMike Cleron <mcleron@google.com>2011-02-04 15:29:28 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-02-04 15:29:28 -0800
commit2d47fd3c3566e5fbe16bcee2ec4be87c6cdc2440 (patch)
treedf03ef70155dd377f0a833645233ba619f955461 /libs
parenta5b8768f01462374aed42e5c602afe65b7e050ef (diff)
parent5a7e828842c26f64bb6e0ef3e0019e1949b245ee (diff)
downloadframeworks_base-2d47fd3c3566e5fbe16bcee2ec4be87c6cdc2440.zip
frameworks_base-2d47fd3c3566e5fbe16bcee2ec4be87c6cdc2440.tar.gz
frameworks_base-2d47fd3c3566e5fbe16bcee2ec4be87c6cdc2440.tar.bz2
Merge "Fix crash when Paths are GCd in hw accelerated apps" into honeycomb
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/DisplayListRenderer.cpp17
-rw-r--r--libs/hwui/DisplayListRenderer.h9
-rw-r--r--libs/hwui/ResourceCache.cpp35
-rw-r--r--libs/hwui/ResourceCache.h4
4 files changed, 65 insertions, 0 deletions
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 2df52ae..d5d2ba0 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -95,6 +95,10 @@ void DisplayList::clearResources() {
delete mPaths.itemAt(i);
}
mPaths.clear();
+ for (size_t i = 0; i < mOriginalPaths.size(); i++) {
+ caches.resourceCache.decrementRefcount(mOriginalPaths.itemAt(i));
+ }
+ mOriginalPaths.clear();
for (size_t i = 0; i < mMatrices.size(); i++) {
delete mMatrices.itemAt(i);
@@ -146,6 +150,13 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde
mPaths.add(paths.itemAt(i));
}
+ const Vector<SkPath*> &originalPaths = recorder.getOriginalPaths();
+ for (size_t i = 0; i < originalPaths.size(); i++) {
+ SkPath* path = originalPaths.itemAt(i);
+ mOriginalPaths.add(path);
+ caches.resourceCache.incrementRefcount(path);
+ }
+
const Vector<SkMatrix*> &matrices = recorder.getMatrices();
for (size_t i = 0; i < matrices.size(); i++) {
mMatrices.add(matrices.itemAt(i));
@@ -519,6 +530,12 @@ void DisplayListRenderer::reset() {
}
mBitmapResources.clear();
+ for (size_t i = 0; i < mOriginalPaths.size(); i++) {
+ SkPath* resource = mOriginalPaths.itemAt(i);
+ caches.resourceCache.decrementRefcount(resource);
+ }
+ mOriginalPaths.clear();
+
for (size_t i = 0; i < mShaders.size(); i++) {
caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
}
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 2d0e30a..f39f37f 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -190,6 +190,7 @@ private:
Vector<SkPaint*> mPaints;
Vector<SkPath*> mPaths;
+ Vector<SkPath*> mOriginalPaths;
Vector<SkMatrix*> mMatrices;
Vector<SkiaShader*> mShaders;
@@ -293,6 +294,10 @@ public:
return mPaths;
}
+ const Vector<SkPath*>& getOriginalPaths() const {
+ return mOriginalPaths;
+ }
+
const Vector<SkMatrix*>& getMatrices() const {
return mMatrices;
}
@@ -371,6 +376,9 @@ private:
if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
if (pathCopy == NULL) {
pathCopy = path;
+ mOriginalPaths.add(path);
+ Caches& caches = Caches::getInstance();
+ caches.resourceCache.incrementRefcount(path);
} else {
pathCopy = new SkPath(*path);
mPaths.add(pathCopy);
@@ -452,6 +460,7 @@ private:
Vector<SkPaint*> mPaints;
DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap;
+ Vector<SkPath*> mOriginalPaths;
Vector<SkPath*> mPaths;
DefaultKeyedVector<SkPath*, SkPath*> mPathMap;
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index 70d117a..87fdfb5 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -65,6 +65,10 @@ void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
incrementRefcount((void*)bitmapResource, kBitmap);
}
+void ResourceCache::incrementRefcount(SkPath* pathResource) {
+ incrementRefcount((void*)pathResource, kPath);
+}
+
void ResourceCache::incrementRefcount(SkiaShader* shaderResource) {
shaderResource->getSkShader()->safeRef();
incrementRefcount((void*) shaderResource, kShader);
@@ -94,6 +98,10 @@ void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
decrementRefcount((void*) bitmapResource);
}
+void ResourceCache::decrementRefcount(SkPath* pathResource) {
+ decrementRefcount((void*) pathResource);
+}
+
void ResourceCache::decrementRefcount(SkiaShader* shaderResource) {
shaderResource->getSkShader()->safeUnref();
decrementRefcount((void*) shaderResource);
@@ -122,6 +130,24 @@ void ResourceCache::recycle(SkBitmap* resource) {
}
}
+void ResourceCache::destructor(SkPath* resource) {
+ Mutex::Autolock _l(mLock);
+ ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
+ if (ref == NULL) {
+ // If we're not tracking this resource, just delete it
+ if (Caches::hasInstance()) {
+ Caches::getInstance().pathCache.removeDeferred(resource);
+ }
+ delete resource;
+ return;
+ }
+ ref->destroyed = true;
+ if (ref->refCount == 0) {
+ deleteResourceReference(resource, ref);
+ return;
+ }
+}
+
void ResourceCache::destructor(SkBitmap* resource) {
Mutex::Autolock _l(mLock);
ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
@@ -192,6 +218,15 @@ void ResourceCache::deleteResourceReference(void* resource, ResourceReference* r
delete bitmap;
}
break;
+ case kPath:
+ {
+ SkPath* path = (SkPath*)resource;
+ if (Caches::hasInstance()) {
+ Caches::getInstance().pathCache.removeDeferred(path);
+ }
+ delete path;
+ }
+ break;
case kShader:
{
SkiaShader* shader = (SkiaShader*)resource;
diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h
index 1bb4390..2a38910 100644
--- a/libs/hwui/ResourceCache.h
+++ b/libs/hwui/ResourceCache.h
@@ -32,6 +32,7 @@ enum ResourceType {
kBitmap,
kShader,
kColorFilter,
+ kPath,
};
class ResourceReference {
@@ -53,15 +54,18 @@ class ResourceCache {
public:
ResourceCache();
~ResourceCache();
+ void incrementRefcount(SkPath* resource);
void incrementRefcount(SkBitmap* resource);
void incrementRefcount(SkiaShader* resource);
void incrementRefcount(SkiaColorFilter* resource);
void incrementRefcount(const void* resource, ResourceType resourceType);
void decrementRefcount(void* resource);
void decrementRefcount(SkBitmap* resource);
+ void decrementRefcount(SkPath* resource);
void decrementRefcount(SkiaShader* resource);
void decrementRefcount(SkiaColorFilter* resource);
void recycle(SkBitmap* resource);
+ void destructor(SkPath* resource);
void destructor(SkBitmap* resource);
void destructor(SkiaShader* resource);
void destructor(SkiaColorFilter* resource);