Index: src/gpu/GrResourceCache.cpp |
diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp |
index 1d32c23abac3fca5deb16c7b986211b029285172..bda124c6ca3b6d3230f0d53058f7199d9bd51e41 100644 |
--- a/src/gpu/GrResourceCache.cpp |
+++ b/src/gpu/GrResourceCache.cpp |
@@ -145,7 +145,8 @@ void GrResourceCache::insertResource(GrGpuResource* resource) { |
fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes); |
#endif |
} |
- if (resource->resourcePriv().getScratchKey().isValid()) { |
+ if (resource->resourcePriv().getScratchKey().isValid() && |
+ !resource->getUniqueKey().isValid()) { |
SkASSERT(!resource->resourcePriv().refsWrappedObjects()); |
fScratchMap.insert(resource->resourcePriv().getScratchKey(), resource); |
} |
@@ -173,7 +174,8 @@ void GrResourceCache::removeResource(GrGpuResource* resource) { |
fBudgetedBytes, "free", fMaxBytes - fBudgetedBytes); |
} |
- if (resource->resourcePriv().getScratchKey().isValid()) { |
+ if (resource->resourcePriv().getScratchKey().isValid() && |
+ !resource->getUniqueKey().isValid()) { |
fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); |
} |
if (resource->getUniqueKey().isValid()) { |
@@ -235,13 +237,15 @@ public: |
AvailableForScratchUse(bool rejectPendingIO) : fRejectPendingIO(rejectPendingIO) { } |
bool operator()(const GrGpuResource* resource) const { |
- if (resource->internalHasRef() || !resource->cacheAccess().isScratch()) { |
- return false; |
- } |
+ SkASSERT(!resource->getUniqueKey().isValid() && |
+ resource->resourcePriv().getScratchKey().isValid()); |
+ if (resource->internalHasRef() || !resource->cacheAccess().isScratch()) { |
+ return false; |
+ } |
return !fRejectPendingIO || !resource->internalHasPendingIO(); |
} |
-private: |
+private: |
bool fRejectPendingIO; |
}; |
@@ -279,7 +283,9 @@ GrGpuResource* GrResourceCache::findAndRefScratchResource(const GrScratchKey& sc |
void GrResourceCache::willRemoveScratchKey(const GrGpuResource* resource) { |
SkASSERT(resource->resourcePriv().getScratchKey().isValid()); |
- fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); |
+ if (!resource->getUniqueKey().isValid()) { |
+ fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); |
+ } |
} |
void GrResourceCache::removeUniqueKey(GrGpuResource* resource) { |
@@ -290,6 +296,11 @@ void GrResourceCache::removeUniqueKey(GrGpuResource* resource) { |
fUniqueHash.remove(resource->getUniqueKey()); |
} |
resource->cacheAccess().removeUniqueKey(); |
+ |
+ if (resource->resourcePriv().getScratchKey().isValid()) { |
+ fScratchMap.insert(resource->resourcePriv().getScratchKey(), resource); |
+ } |
+ |
this->validate(); |
} |
@@ -297,15 +308,21 @@ void GrResourceCache::changeUniqueKey(GrGpuResource* resource, const GrUniqueKey |
SkASSERT(resource); |
SkASSERT(this->isInCache(resource)); |
- // Remove the entry for this resource if it already has a unique key. |
- if (resource->getUniqueKey().isValid()) { |
- SkASSERT(resource == fUniqueHash.find(resource->getUniqueKey())); |
- fUniqueHash.remove(resource->getUniqueKey()); |
- SkASSERT(nullptr == fUniqueHash.find(resource->getUniqueKey())); |
- } |
- |
// If another resource has the new key, remove its key then install the key on this resource. |
if (newKey.isValid()) { |
+ // Remove the entry for this resource if it already has a unique key. |
+ if (resource->getUniqueKey().isValid()) { |
+ SkASSERT(resource == fUniqueHash.find(resource->getUniqueKey())); |
+ fUniqueHash.remove(resource->getUniqueKey()); |
+ SkASSERT(nullptr == fUniqueHash.find(resource->getUniqueKey())); |
+ } else { |
+ // 'resource' didn't have a valid unique key before so it is switching sides. Remove it |
+ // from the ScratchMap |
+ if (resource->resourcePriv().getScratchKey().isValid()) { |
+ fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); |
+ } |
+ } |
+ |
if (GrGpuResource* old = fUniqueHash.find(newKey)) { |
// If the old resource using the key is purgeable and is unreachable, then remove it. |
if (!old->resourcePriv().getScratchKey().isValid() && old->isPurgeable()) { |
@@ -314,15 +331,14 @@ void GrResourceCache::changeUniqueKey(GrGpuResource* resource, const GrUniqueKey |
SkDEBUGCODE(resource->cacheAccess().removeUniqueKey();) |
old->cacheAccess().release(); |
} else { |
- fUniqueHash.remove(newKey); |
- old->cacheAccess().removeUniqueKey(); |
+ this->removeUniqueKey(old); |
} |
} |
SkASSERT(nullptr == fUniqueHash.find(newKey)); |
resource->cacheAccess().setUniqueKey(newKey); |
fUniqueHash.add(resource); |
} else { |
- resource->cacheAccess().removeUniqueKey(); |
+ this->removeUniqueKey(resource); |
} |
this->validate(); |
@@ -657,24 +673,32 @@ void GrResourceCache::validate() const { |
++fLocked; |
} |
+ const GrScratchKey& scratchKey = resource->resourcePriv().getScratchKey(); |
+ const GrUniqueKey& uniqueKey = resource->getUniqueKey(); |
+ |
if (resource->cacheAccess().isScratch()) { |
- SkASSERT(!resource->getUniqueKey().isValid()); |
+ SkASSERT(!uniqueKey.isValid()); |
++fScratch; |
- SkASSERT(fScratchMap->countForKey(resource->resourcePriv().getScratchKey())); |
+ SkASSERT(fScratchMap->countForKey(scratchKey)); |
SkASSERT(!resource->resourcePriv().refsWrappedObjects()); |
- } else if (resource->resourcePriv().getScratchKey().isValid()) { |
+ } else if (scratchKey.isValid()) { |
SkASSERT(SkBudgeted::kNo == resource->resourcePriv().isBudgeted() || |
- resource->getUniqueKey().isValid()); |
- ++fCouldBeScratch; |
- SkASSERT(fScratchMap->countForKey(resource->resourcePriv().getScratchKey())); |
+ uniqueKey.isValid()); |
+ if (!uniqueKey.isValid()) { |
+ ++fCouldBeScratch; |
+ SkASSERT(fScratchMap->countForKey(scratchKey)); |
+ } |
SkASSERT(!resource->resourcePriv().refsWrappedObjects()); |
} |
- const GrUniqueKey& uniqueKey = resource->getUniqueKey(); |
if (uniqueKey.isValid()) { |
++fContent; |
SkASSERT(fUniqueHash->find(uniqueKey) == resource); |
SkASSERT(!resource->resourcePriv().refsWrappedObjects()); |
SkASSERT(SkBudgeted::kYes == resource->resourcePriv().isBudgeted()); |
+ |
+ if (scratchKey.isValid()) { |
+ SkASSERT(!fScratchMap->has(resource, scratchKey)); |
+ } |
} |
if (SkBudgeted::kYes == resource->resourcePriv().isBudgeted()) { |
@@ -684,6 +708,19 @@ void GrResourceCache::validate() const { |
} |
}; |
+ { |
+ ScratchMap::ConstIter iter(&fScratchMap); |
+ |
+ int count = 0; |
+ for ( ; !iter.done(); ++iter) { |
+ const GrGpuResource* resource = *iter; |
+ SkASSERT(resource->resourcePriv().getScratchKey().isValid()); |
+ SkASSERT(!resource->getUniqueKey().isValid()); |
+ count++; |
+ } |
+ SkASSERT(count == fScratchMap.count()); // ensure the iterator is working correctly |
+ } |
+ |
Stats stats(this); |
for (int i = 0; i < fNonpurgeableResources.count(); ++i) { |