| Index: src/gpu/GrResourceCache.cpp
|
| diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp
|
| index 26f7592548f7d6b4cb7b80084fc4c7eb04af12dc..529c3a5d1db8979d1d16d151f30d18aa9d2d76ce 100644
|
| --- a/src/gpu/GrResourceCache.cpp
|
| +++ b/src/gpu/GrResourceCache.cpp
|
| @@ -13,6 +13,16 @@
|
|
|
| DECLARE_SKMESSAGEBUS_MESSAGE(GrResourceInvalidatedMessage);
|
|
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +
|
| +void GrCacheable::didChangeGpuMemorySize() const {
|
| + if (this->isInCache()) {
|
| + fCacheEntry->didChangeResourceSize();
|
| + }
|
| +}
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +
|
| GrResourceKey::ResourceType GrResourceKey::GenerateResourceType() {
|
| static int32_t gNextType = 0;
|
|
|
| @@ -26,8 +36,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 +56,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::didChangeResourceSize() {
|
| + size_t oldSize = fCachedSize;
|
| + fCachedSize = fResource->gpuMemorySize();
|
| + if (fCachedSize > oldSize) {
|
| + fResourceCache->didIncreaseResourceSize(this, fCachedSize - oldSize);
|
| + } else if (fCachedSize < oldSize) {
|
| + fResourceCache->didDecreaseResourceSize(this, oldSize - fCachedSize);
|
| + }
|
| +}
|
| +
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| GrResourceCache::GrResourceCache(int maxCount, size_t maxBytes) :
|
| @@ -115,7 +143,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 +158,7 @@ void GrResourceCache::internalDetach(GrResourceCacheEntry* entry,
|
| SkASSERT(kAccountFor_BudgetBehavior == behavior);
|
|
|
| fEntryCount -= 1;
|
| - fEntryBytes -= entry->resource()->gpuMemorySize();
|
| + fEntryBytes -= entry->fCachedSize;
|
| }
|
| }
|
|
|
| @@ -141,12 +169,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 +236,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 +251,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);
|
| @@ -239,11 +270,12 @@ void GrResourceCache::removeInvalidResource(GrResourceCacheEntry* entry) {
|
| // the client called GrContext::contextDestroyed() to notify Gr,
|
| // and then later an SkGpuDevice's destructor releases its backing
|
| // texture (which was invalidated at contextDestroyed time).
|
| + // TODO: Safely delete the GrResourceCacheEntry as well.
|
| fClientDetachedCount -= 1;
|
| fEntryCount -= 1;
|
| - size_t size = entry->resource()->gpuMemorySize();
|
| - fClientDetachedBytes -= size;
|
| - fEntryBytes -= size;
|
| + fClientDetachedBytes -= entry->fCachedSize;
|
| + fEntryBytes -= entry->fCachedSize;
|
| + entry->fCachedSize = 0;
|
| }
|
|
|
| void GrResourceCache::makeNonExclusive(GrResourceCacheEntry* entry) {
|
| @@ -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::didIncreaseResourceSize(const GrResourceCacheEntry* entry, size_t amountInc) {
|
| + fEntryBytes += amountInc;
|
| + if (entry->fIsExclusive) {
|
| + fClientDetachedBytes += amountInc;
|
| + }
|
| + this->purgeAsNeeded();
|
| +}
|
| +
|
| +void GrResourceCache::didDecreaseResourceSize(const GrResourceCacheEntry* entry, size_t amountDec) {
|
| + fEntryBytes -= amountDec;
|
| + if (entry->fIsExclusive) {
|
| + fClientDetachedBytes -= amountDec;
|
| + }
|
| +#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
|
|
|