Index: src/gpu/GrResourceCache.cpp |
diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp |
index 59c22025899d326dd4551cc350cb52e0db8cf869..c9331c78b000876d87198dad98c111ee7a9c7ee4 100644 |
--- a/src/gpu/GrResourceCache.cpp |
+++ b/src/gpu/GrResourceCache.cpp |
@@ -13,6 +13,15 @@ |
DECLARE_SKMESSAGEBUS_MESSAGE(GrResourceInvalidatedMessage); |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
+void GrCacheable::onResourceSizeChanged() const { |
+ if (this->isInCache()) |
+ fCacheEntry->onResourceSizeChanged(); |
bsalomon
2014/04/28 21:08:33
{ }
Chris Dalton
2014/04/28 22:30:58
Done.
|
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
GrResourceKey::ResourceType GrResourceKey::GenerateResourceType() { |
static int32_t gNextType = 0; |
@@ -26,8 +35,14 @@ GrResourceKey::ResourceType GrResourceKey::GenerateResourceType() { |
/////////////////////////////////////////////////////////////////////////////// |
-GrResourceCacheEntry::GrResourceCacheEntry(const GrResourceKey& key, GrCacheable* resource) |
- : fKey(key), fResource(resource) { |
+GrResourceCacheEntry::GrResourceCacheEntry(GrResourceCache* resourceCache, |
+ const GrResourceKey& key, |
+ GrCacheable* resource) |
+ : fResourceCache(resourceCache), |
+ fKey(key), |
+ fResource(resource), |
+ fCachedSize(resource->gpuMemorySize()), |
+ fIsExclusive(false) { |
// we assume ownership of the resource, and will unref it when we die |
SkASSERT(resource); |
resource->ref(); |
@@ -40,12 +55,24 @@ GrResourceCacheEntry::~GrResourceCacheEntry() { |
#ifdef SK_DEBUG |
void GrResourceCacheEntry::validate() const { |
+ SkASSERT(fResourceCache); |
SkASSERT(fResource); |
SkASSERT(fResource->getCacheEntry() == this); |
+ SkASSERT(fResource->gpuMemorySize() == fCachedSize); |
fResource->validate(); |
} |
#endif |
+void GrResourceCacheEntry::onResourceSizeChanged() { |
+ size_t oldSize = fCachedSize; |
+ fCachedSize = fResource->gpuMemorySize(); |
+ if (fCachedSize > oldSize) { |
+ fResourceCache->onResourceSizeIncreased(this, fCachedSize - oldSize); |
+ } else if (fCachedSize < oldSize) { |
+ fResourceCache->onResourceSizeDecreased(this, oldSize - fCachedSize); |
+ } |
+} |
+ |
/////////////////////////////////////////////////////////////////////////////// |
GrResourceCache::GrResourceCache(int maxCount, size_t maxBytes) : |
@@ -115,7 +142,7 @@ void GrResourceCache::internalDetach(GrResourceCacheEntry* entry, |
// update our stats |
if (kIgnore_BudgetBehavior == behavior) { |
fClientDetachedCount += 1; |
- fClientDetachedBytes += entry->resource()->gpuMemorySize(); |
+ fClientDetachedBytes += entry->fCachedSize; |
#if GR_CACHE_STATS |
if (fHighWaterClientDetachedCount < fClientDetachedCount) { |
@@ -130,7 +157,7 @@ void GrResourceCache::internalDetach(GrResourceCacheEntry* entry, |
SkASSERT(kAccountFor_BudgetBehavior == behavior); |
fEntryCount -= 1; |
- fEntryBytes -= entry->resource()->gpuMemorySize(); |
+ fEntryBytes -= entry->fCachedSize; |
} |
} |
@@ -141,12 +168,12 @@ void GrResourceCache::attachToHead(GrResourceCacheEntry* entry, |
// update our stats |
if (kIgnore_BudgetBehavior == behavior) { |
fClientDetachedCount -= 1; |
- fClientDetachedBytes -= entry->resource()->gpuMemorySize(); |
+ fClientDetachedBytes -= entry->fCachedSize; |
} else { |
SkASSERT(kAccountFor_BudgetBehavior == behavior); |
fEntryCount += 1; |
- fEntryBytes += entry->resource()->gpuMemorySize(); |
+ fEntryBytes += entry->fCachedSize; |
#if GR_CACHE_STATS |
if (fHighWaterEntryCount < fEntryCount) { |
@@ -208,7 +235,7 @@ void GrResourceCache::addResource(const GrResourceKey& key, |
SkASSERT(!fPurging); |
GrAutoResourceCacheValidate atcv(this); |
- GrResourceCacheEntry* entry = SkNEW_ARGS(GrResourceCacheEntry, (key, resource)); |
+ GrResourceCacheEntry* entry = SkNEW_ARGS(GrResourceCacheEntry, (this, key, resource)); |
resource->setCacheEntry(entry); |
this->attachToHead(entry); |
@@ -223,6 +250,9 @@ void GrResourceCache::addResource(const GrResourceKey& key, |
void GrResourceCache::makeExclusive(GrResourceCacheEntry* entry) { |
GrAutoResourceCacheValidate atcv(this); |
+ SkASSERT(!entry->fIsExclusive); |
+ entry->fIsExclusive = true; |
+ |
// When scratch textures are detached (to hide them from future finds) they |
// still count against the resource budget |
this->internalDetach(entry, kIgnore_BudgetBehavior); |
@@ -241,7 +271,9 @@ void GrResourceCache::removeInvalidResource(GrResourceCacheEntry* entry) { |
// texture (which was invalidated at contextDestroyed time). |
fClientDetachedCount -= 1; |
fEntryCount -= 1; |
- size_t size = entry->resource()->gpuMemorySize(); |
+ size_t size = entry->fCachedSize; |
+ entry->fResource->setCacheEntry(NULL); |
+ delete entry; |
fClientDetachedBytes -= size; |
fEntryBytes -= size; |
} |
@@ -259,11 +291,32 @@ void GrResourceCache::makeNonExclusive(GrResourceCacheEntry* entry) { |
// alter the budget information. |
attachToHead(entry, kIgnore_BudgetBehavior); |
fCache.insert(entry->key(), entry); |
+ |
+ SkASSERT(entry->fIsExclusive); |
+ entry->fIsExclusive = false; |
} else { |
this->removeInvalidResource(entry); |
} |
} |
+void GrResourceCache::onResourceSizeIncreased(const GrResourceCacheEntry* entry, size_t amount) { |
+ fEntryBytes += amount; |
+ if (entry->fIsExclusive) { |
+ fClientDetachedBytes += amount; |
+ } |
+ this->purgeAsNeeded(); |
+} |
+ |
+void GrResourceCache::onResourceSizeDecreased(const GrResourceCacheEntry* entry, size_t amount) { |
+ fEntryBytes -= amount; |
+ if (entry->fIsExclusive) { |
+ fClientDetachedBytes -= amount; |
+ } |
+#ifdef SK_DEBUG |
+ this->validate(); |
+#endif |
+} |
+ |
/** |
* Destroying a resource may potentially trigger the unlock of additional |
* resources which in turn will trigger a nested purge. We block the nested |