summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2014-12-04 15:20:29 -0500
committerDerek Sollenberger <djsollen@google.com>2015-01-09 13:56:56 -0500
commit3d4eed7f1aa99401dabe2e45b82f98fb4fc2d754 (patch)
treee727b03577a823f638cab2f76a8a1161b73662eb /libs
parent83eb4443a9d24f2ae4a1e516354748850c10d06b (diff)
downloadframeworks_base-3d4eed7f1aa99401dabe2e45b82f98fb4fc2d754.zip
frameworks_base-3d4eed7f1aa99401dabe2e45b82f98fb4fc2d754.tar.gz
frameworks_base-3d4eed7f1aa99401dabe2e45b82f98fb4fc2d754.tar.bz2
Update HWUI to store its own SkBitmap objects
This enables us to... 1) simplify the lifecycle/ownership between Java and HWUI 2) remove DisplayListRenderer::drawBitmapData and associated logic 3) track pixel lifecycle using standard SkPixelRef refcounting 4) Remove uncessary calls to ref/unref the bitmap's pixels and colorTable Change-Id: I3c95078da20995444f6388a029414280fd654318
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/DisplayList.cpp7
-rw-r--r--libs/hwui/DisplayList.h1
-rw-r--r--libs/hwui/DisplayListOp.h21
-rw-r--r--libs/hwui/DisplayListRenderer.cpp7
-rw-r--r--libs/hwui/DisplayListRenderer.h14
-rwxr-xr-xlibs/hwui/OpenGLRenderer.cpp18
-rwxr-xr-xlibs/hwui/OpenGLRenderer.h1
-rw-r--r--libs/hwui/RenderNode.cpp5
-rw-r--r--libs/hwui/Renderer.h1
-rw-r--r--libs/hwui/ResourceCache.cpp161
-rw-r--r--libs/hwui/ResourceCache.h53
-rw-r--r--libs/hwui/TextureCache.cpp6
-rw-r--r--libs/hwui/TextureCache.h4
13 files changed, 113 insertions, 186 deletions
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index 249ada0..9832e60 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -46,12 +46,6 @@ void DisplayListData::cleanupResources() {
resourceCache.decrementRefcountLocked(bitmapResources.itemAt(i));
}
- for (size_t i = 0; i < ownedBitmapResources.size(); i++) {
- const SkBitmap* bitmap = ownedBitmapResources.itemAt(i);
- resourceCache.decrementRefcountLocked(bitmap);
- resourceCache.destructorLocked(bitmap);
- }
-
for (size_t i = 0; i < patchResources.size(); i++) {
resourceCache.decrementRefcountLocked(patchResources.itemAt(i));
}
@@ -63,7 +57,6 @@ void DisplayListData::cleanupResources() {
resourceCache.unlock();
bitmapResources.clear();
- ownedBitmapResources.clear();
patchResources.clear();
sourcePaths.clear();
paints.clear();
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index cfd60ad..011b509 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -134,7 +134,6 @@ public:
int projectionReceiveIndex;
Vector<const SkBitmap*> bitmapResources;
- Vector<const SkBitmap*> ownedBitmapResources;
Vector<const Res_png_9patch*> patchResources;
std::vector<std::unique_ptr<const SkPaint>> paints;
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 1b5af49..36c14c4 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -734,27 +734,6 @@ private:
Rect mSrc;
};
-class DrawBitmapDataOp : public DrawBitmapOp {
-public:
- DrawBitmapDataOp(const SkBitmap* bitmap, const SkPaint* paint)
- : DrawBitmapOp(bitmap, paint) {}
-
- virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
- renderer.drawBitmapData(mBitmap, mPaint);
- }
-
- virtual void output(int level, uint32_t logFlags) const override {
- OP_LOG("Draw bitmap %p", mBitmap);
- }
-
- virtual const char* name() override { return "DrawBitmapData"; }
-
- virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
- const DeferredDisplayState& state) override {
- deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
- }
-};
-
class DrawBitmapMeshOp : public DrawBoundedOp {
public:
DrawBitmapMeshOp(const SkBitmap* bitmap, int meshWidth, int meshHeight,
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index ca21e4e..c7de03a 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -266,13 +266,6 @@ void DisplayListRenderer::drawBitmap(const SkBitmap& bitmap, float srcLeft, floa
}
}
-void DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) {
- bitmap = refBitmapData(bitmap);
- paint = refPaint(paint);
-
- addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, paint));
-}
-
void DisplayListRenderer::drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
const float* vertices, const int* colors, const SkPaint* paint) {
int vertexCount = (meshWidth + 1) * (meshHeight + 1);
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 01fcdd3..8f8d24c 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -101,8 +101,6 @@ public:
// Bitmap-based
void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
- // TODO: move drawBitmapData() to Canvas.h
- void drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint);
// TODO: move drawPatch() to Canvas.h
void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
float left, float top, float right, float bottom, const SkPaint* paint);
@@ -367,15 +365,9 @@ private:
// correctly, such as creating the bitmap from scratch, drawing with it, changing its
// contents, and drawing again. The only fix would be to always copy it the first time,
// which doesn't seem worth the extra cycles for this unlikely case.
- mDisplayListData->bitmapResources.add(bitmap);
- mResourceCache.incrementRefcount(bitmap);
- return bitmap;
- }
-
- inline const SkBitmap* refBitmapData(const SkBitmap* bitmap) {
- mDisplayListData->ownedBitmapResources.add(bitmap);
- mResourceCache.incrementRefcount(bitmap);
- return bitmap;
+ const SkBitmap* cachedBitmap = mResourceCache.insert(bitmap);
+ mDisplayListData->bitmapResources.add(cachedBitmap);
+ return cachedBitmap;
}
inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) {
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 3c8fb8b..d1e51e1 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2006,24 +2006,6 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
mDirty = true;
}
-void OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) {
- if (quickRejectSetupScissor(0, 0, bitmap->width(), bitmap->height())) {
- return;
- }
-
- mCaches.activeTexture(0);
- Texture* texture = mCaches.textureCache.getTransient(bitmap);
- const AutoTexture autoCleanup(texture);
-
- if (CC_UNLIKELY(bitmap->colorType() == kAlpha_8_SkColorType)) {
- drawAlphaBitmap(texture, 0, 0, paint);
- } else {
- drawTextureRect(0, 0, bitmap->width(), bitmap->height(), texture, paint);
- }
-
- mDirty = true;
-}
-
void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
const float* vertices, const int* colors, const SkPaint* paint) {
if (!vertices || mState.currentlyIgnored()) {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 9d9b3d2..75e79d6 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -162,7 +162,6 @@ public:
virtual void drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, const SkPaint* paint) override;
- virtual void drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) override;
virtual void drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
const float* vertices, const int* colors, const SkPaint* paint) override;
void drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 5a7ea40..23462cc 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -338,11 +338,6 @@ void RenderNode::prepareSubTree(TreeInfo& info, DisplayListData* subtree) {
if (subtree) {
TextureCache& cache = Caches::getInstance().textureCache;
info.out.hasFunctors |= subtree->functors.size();
- // TODO: Fix ownedBitmapResources to not require disabling prepareTextures
- // and thus falling out of async drawing path.
- if (subtree->ownedBitmapResources.size()) {
- info.prepareTextures = false;
- }
for (size_t i = 0; info.prepareTextures && i < subtree->bitmapResources.size(); i++) {
info.prepareTextures = cache.prefetchAndMarkInUse(subtree->bitmapResources[i]);
}
diff --git a/libs/hwui/Renderer.h b/libs/hwui/Renderer.h
index 3240bbc..48d83b9 100644
--- a/libs/hwui/Renderer.h
+++ b/libs/hwui/Renderer.h
@@ -155,7 +155,6 @@ public:
virtual void drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, const SkPaint* paint) = 0;
- virtual void drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) = 0;
virtual void drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
const float* vertices, const int* colors, const SkPaint* paint) = 0;
virtual void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index 45c27c2..2d1adc5 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -16,7 +16,6 @@
#define LOG_TAG "OpenGLRenderer"
-#include <SkPixelRef.h>
#include "ResourceCache.h"
#include "Caches.h"
@@ -37,8 +36,8 @@ void ResourceCache::logCache() {
ResourceReference* ref = mCache->valueAt(i);
ALOGD(" ResourceCache: mCache(%zu): resource, ref = 0x%p, 0x%p",
i, mCache->keyAt(i), mCache->valueAt(i));
- ALOGD(" ResourceCache: mCache(%zu): refCount, recycled, destroyed, type = %d, %d, %d, %d",
- i, ref->refCount, ref->recycled, ref->destroyed, ref->resourceType);
+ ALOGD(" ResourceCache: mCache(%zu): refCount, destroyed, type = %d, %d, %d",
+ i, ref->refCount, ref->destroyed, ref->resourceType);
}
}
@@ -60,13 +59,24 @@ void ResourceCache::unlock() {
mLock.unlock();
}
-void ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) {
+const SkBitmap* ResourceCache::insert(const SkBitmap* bitmapResource) {
Mutex::Autolock _l(mLock);
- incrementRefcountLocked(resource, resourceType);
+
+ BitmapKey bitmapKey(bitmapResource);
+ ssize_t index = mBitmapCache.indexOfKey(bitmapKey);
+ if (index == NAME_NOT_FOUND) {
+ SkBitmap* cachedBitmap = new SkBitmap(*bitmapResource);
+ index = mBitmapCache.add(bitmapKey, cachedBitmap);
+ return cachedBitmap;
+ }
+
+ mBitmapCache.keyAt(index).mRefCount++;
+ return mBitmapCache.valueAt(index);
}
-void ResourceCache::incrementRefcount(const SkBitmap* bitmapResource) {
- incrementRefcount((void*) bitmapResource, kBitmap);
+void ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) {
+ Mutex::Autolock _l(mLock);
+ incrementRefcountLocked(resource, resourceType);
}
void ResourceCache::incrementRefcount(const SkPath* pathResource) {
@@ -87,25 +97,14 @@ void ResourceCache::incrementRefcountLocked(void* resource, ResourceType resourc
ref->refCount++;
}
-void ResourceCache::incrementRefcountLocked(const SkBitmap* bitmapResource) {
- incrementRefcountLocked((void*) bitmapResource, kBitmap);
-}
-
-void ResourceCache::incrementRefcountLocked(const SkPath* pathResource) {
- incrementRefcountLocked((void*) pathResource, kPath);
-}
-
-void ResourceCache::incrementRefcountLocked(const Res_png_9patch* patchResource) {
- incrementRefcountLocked((void*) patchResource, kNinePatch);
-}
-
void ResourceCache::decrementRefcount(void* resource) {
Mutex::Autolock _l(mLock);
decrementRefcountLocked(resource);
}
void ResourceCache::decrementRefcount(const SkBitmap* bitmapResource) {
- decrementRefcount((void*) bitmapResource);
+ Mutex::Autolock _l(mLock);
+ decrementRefcountLocked(bitmapResource);
}
void ResourceCache::decrementRefcount(const SkPath* pathResource) {
@@ -130,7 +129,20 @@ void ResourceCache::decrementRefcountLocked(void* resource) {
}
void ResourceCache::decrementRefcountLocked(const SkBitmap* bitmapResource) {
- decrementRefcountLocked((void*) bitmapResource);
+ BitmapKey bitmapKey(bitmapResource);
+ ssize_t index = mBitmapCache.indexOfKey(bitmapKey);
+
+ LOG_ALWAYS_FATAL_IF(index == NAME_NOT_FOUND,
+ "Decrementing the reference of an untracked Bitmap");
+
+ const BitmapKey& cacheEntry = mBitmapCache.keyAt(index);
+ if (cacheEntry.mRefCount == 1) {
+ // delete the bitmap and remove it from the cache
+ delete mBitmapCache.valueAt(index);
+ mBitmapCache.removeItemsAt(index);
+ } else {
+ cacheEntry.mRefCount--;
+ }
}
void ResourceCache::decrementRefcountLocked(const SkPath* pathResource) {
@@ -164,28 +176,6 @@ void ResourceCache::destructorLocked(SkPath* resource) {
}
}
-void ResourceCache::destructor(const SkBitmap* resource) {
- Mutex::Autolock _l(mLock);
- destructorLocked(resource);
-}
-
-void ResourceCache::destructorLocked(const SkBitmap* resource) {
- ssize_t index = mCache->indexOfKey(resource);
- ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : nullptr;
- if (ref == nullptr) {
- // If we're not tracking this resource, just delete it
- if (Caches::hasInstance()) {
- Caches::getInstance().textureCache.releaseTexture(resource);
- }
- delete resource;
- return;
- }
- ref->destroyed = true;
- if (ref->refCount == 0) {
- deleteResourceReferenceLocked(resource, ref);
- }
-}
-
void ResourceCache::destructor(Res_png_9patch* resource) {
Mutex::Autolock _l(mLock);
destructorLocked(resource);
@@ -212,64 +202,12 @@ void ResourceCache::destructorLocked(Res_png_9patch* resource) {
}
/**
- * 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) {
- if (Caches::hasInstance()) {
- Caches::getInstance().textureCache.releaseTexture(resource);
- }
- // not tracking this resource; just recycle the pixel data
- resource->setPixels(nullptr, nullptr);
- return true;
- }
- ResourceReference* ref = mCache->valueAt(index);
- if (ref == nullptr) {
- // 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::deleteResourceReferenceLocked(const void* resource, ResourceReference* ref) {
- if (ref->recycled && ref->resourceType == kBitmap) {
- SkBitmap* bitmap = (SkBitmap*) resource;
- if (Caches::hasInstance()) {
- Caches::getInstance().textureCache.releaseTexture(bitmap);
- }
- bitmap->setPixels(nullptr, nullptr);
- }
if (ref->destroyed) {
switch (ref->resourceType) {
- case kBitmap: {
- SkBitmap* bitmap = (SkBitmap*) resource;
- if (Caches::hasInstance()) {
- Caches::getInstance().textureCache.releaseTexture(bitmap);
- }
- delete bitmap;
- }
- break;
case kPath: {
SkPath* path = (SkPath*) resource;
if (Caches::hasInstance()) {
@@ -296,5 +234,38 @@ void ResourceCache::deleteResourceReferenceLocked(const void* resource, Resource
delete ref;
}
+///////////////////////////////////////////////////////////////////////////////
+// Bitmap Key
+///////////////////////////////////////////////////////////////////////////////
+
+void BitmapKey::operator=(const BitmapKey& other) {
+ this->mRefCount = other.mRefCount;
+ this->mBitmapDimensions = other.mBitmapDimensions;
+ this->mPixelRefOrigin = other.mPixelRefOrigin;
+ this->mPixelRefStableID = other.mPixelRefStableID;
+}
+
+bool BitmapKey::operator==(const BitmapKey& other) const {
+ return mPixelRefStableID == other.mPixelRefStableID &&
+ mPixelRefOrigin == other.mPixelRefOrigin &&
+ mBitmapDimensions == other.mBitmapDimensions;
+}
+
+bool BitmapKey::operator<(const BitmapKey& other) const {
+ if (mPixelRefStableID != other.mPixelRefStableID) {
+ return mPixelRefStableID < other.mPixelRefStableID;
+ }
+ if (mPixelRefOrigin.x() != other.mPixelRefOrigin.x()) {
+ return mPixelRefOrigin.x() < other.mPixelRefOrigin.x();
+ }
+ if (mPixelRefOrigin.y() != other.mPixelRefOrigin.y()) {
+ return mPixelRefOrigin.y() < other.mPixelRefOrigin.y();
+ }
+ if (mBitmapDimensions.width() != other.mBitmapDimensions.width()) {
+ return mBitmapDimensions.width() < other.mBitmapDimensions.width();
+ }
+ return mBitmapDimensions.height() < other.mBitmapDimensions.height();
+}
+
}; // namespace uirenderer
}; // namespace android
diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h
index a252f6c..c6483ac 100644
--- a/libs/hwui/ResourceCache.h
+++ b/libs/hwui/ResourceCache.h
@@ -21,6 +21,7 @@
#include <SkBitmap.h>
#include <SkPath.h>
+#include <SkPixelRef.h>
#include <utils/KeyedVector.h>
#include <utils/Singleton.h>
@@ -36,7 +37,6 @@ class Layer;
* Type of Resource being cached
*/
enum ResourceType {
- kBitmap,
kNinePatch,
kPath
};
@@ -45,15 +45,45 @@ class ResourceReference {
public:
ResourceReference(ResourceType type) {
- refCount = 0; recycled = false; destroyed = false; resourceType = type;
+ refCount = 0; destroyed = false; resourceType = type;
}
int refCount;
- bool recycled;
bool destroyed;
ResourceType resourceType;
};
+class BitmapKey {
+public:
+ BitmapKey(const SkBitmap* bitmap)
+ : mRefCount(1)
+ , mBitmapDimensions(bitmap->dimensions())
+ , mPixelRefOrigin(bitmap->pixelRefOrigin())
+ , mPixelRefStableID(bitmap->pixelRef()->getStableID()) { }
+
+ void operator=(const BitmapKey& other);
+ bool operator==(const BitmapKey& other) const;
+ bool operator<(const BitmapKey& other) const;
+
+private:
+ // This constructor is only used by the KeyedVector implementation
+ BitmapKey()
+ : mRefCount(-1)
+ , mBitmapDimensions(SkISize::Make(0,0))
+ , mPixelRefOrigin(SkIPoint::Make(0,0))
+ , mPixelRefStableID(0) { }
+
+ // reference count of all HWUI object using this bitmap
+ mutable int mRefCount;
+
+ SkISize mBitmapDimensions;
+ SkIPoint mPixelRefOrigin;
+ uint32_t mPixelRefStableID;
+
+ friend class ResourceCache;
+ friend class android::key_value_pair_t<BitmapKey, SkBitmap*>;
+};
+
class ANDROID_API ResourceCache: public Singleton<ResourceCache> {
ResourceCache();
~ResourceCache();
@@ -69,14 +99,15 @@ public:
void lock();
void unlock();
+ /**
+ * The cache stores a copy of the provided resource or refs an existing resource
+ * if the bitmap has previously been inserted and returns the cached copy.
+ */
+ const SkBitmap* insert(const SkBitmap* resource);
+
void incrementRefcount(const SkPath* resource);
- void incrementRefcount(const SkBitmap* resource);
void incrementRefcount(const Res_png_9patch* resource);
- void incrementRefcountLocked(const SkPath* resource);
- void incrementRefcountLocked(const SkBitmap* resource);
- void incrementRefcountLocked(const Res_png_9patch* resource);
-
void decrementRefcount(const SkBitmap* resource);
void decrementRefcount(const SkPath* resource);
void decrementRefcount(const Res_png_9patch* resource);
@@ -86,16 +117,11 @@ public:
void decrementRefcountLocked(const Res_png_9patch* resource);
void destructor(SkPath* resource);
- void destructor(const SkBitmap* resource);
void destructor(Res_png_9patch* resource);
void destructorLocked(SkPath* resource);
- void destructorLocked(const SkBitmap* resource);
void destructorLocked(Res_png_9patch* resource);
- bool recycle(SkBitmap* resource);
- bool recycleLocked(SkBitmap* resource);
-
private:
void deleteResourceReferenceLocked(const void* resource, ResourceReference* ref);
@@ -115,6 +141,7 @@ private:
mutable Mutex mLock;
KeyedVector<const void*, ResourceReference*>* mCache;
+ KeyedVector<BitmapKey, SkBitmap*> mBitmapCache;
};
}; // namespace uirenderer
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 7dc2480..b4d3708 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -233,11 +233,9 @@ Texture* TextureCache::getTransient(const SkBitmap* bitmap) {
return texture;
}
-void TextureCache::releaseTexture(const SkBitmap* bitmap) {
- if (!bitmap || !bitmap->pixelRef()) return;
-
+void TextureCache::releaseTexture(uint32_t pixelRefStableID) {
Mutex::Autolock _l(mLock);
- mGarbage.push(bitmap->pixelRef()->getStableID());
+ mGarbage.push(pixelRefStableID);
}
void TextureCache::clearGarbage() {
diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h
index 0e33e4c..b97d92d 100644
--- a/libs/hwui/TextureCache.h
+++ b/libs/hwui/TextureCache.h
@@ -88,10 +88,10 @@ public:
Texture* getTransient(const SkBitmap* bitmap);
/**
- * Removes the texture associated with the specified bitmap. This is meant
+ * Removes the texture associated with the specified pixelRef. This is meant
* to be called from threads that are not the EGL context thread.
*/
- void releaseTexture(const SkBitmap* bitmap);
+ ANDROID_API void releaseTexture(uint32_t pixelRefStableID);
/**
* Process deferred removals.
*/