| 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) {
|
|
|