| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 | 8 |
| 9 #include "GrResourceCache.h" | 9 #include "GrResourceCache.h" |
| 10 #include "GrGpuResourceCacheAccess.h" | 10 #include "GrGpuResourceCacheAccess.h" |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 if (SkBudgeted::kYes == resource->resourcePriv().isBudgeted()) { | 138 if (SkBudgeted::kYes == resource->resourcePriv().isBudgeted()) { |
| 139 ++fBudgetedCount; | 139 ++fBudgetedCount; |
| 140 fBudgetedBytes += size; | 140 fBudgetedBytes += size; |
| 141 TRACE_COUNTER2(TRACE_DISABLED_BY_DEFAULT("skia.gpu.cache"), "skia budget
", "used", | 141 TRACE_COUNTER2(TRACE_DISABLED_BY_DEFAULT("skia.gpu.cache"), "skia budget
", "used", |
| 142 fBudgetedBytes, "free", fMaxBytes - fBudgetedBytes); | 142 fBudgetedBytes, "free", fMaxBytes - fBudgetedBytes); |
| 143 #if GR_CACHE_STATS | 143 #if GR_CACHE_STATS |
| 144 fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount
); | 144 fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount
); |
| 145 fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes
); | 145 fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes
); |
| 146 #endif | 146 #endif |
| 147 } | 147 } |
| 148 if (resource->resourcePriv().getScratchKey().isValid()) { | 148 if (resource->resourcePriv().getScratchKey().isValid() && |
| 149 !resource->getUniqueKey().isValid()) { |
| 149 SkASSERT(!resource->resourcePriv().refsWrappedObjects()); | 150 SkASSERT(!resource->resourcePriv().refsWrappedObjects()); |
| 150 fScratchMap.insert(resource->resourcePriv().getScratchKey(), resource); | 151 fScratchMap.insert(resource->resourcePriv().getScratchKey(), resource); |
| 151 } | 152 } |
| 152 | 153 |
| 153 this->purgeAsNeeded(); | 154 this->purgeAsNeeded(); |
| 154 } | 155 } |
| 155 | 156 |
| 156 void GrResourceCache::removeResource(GrGpuResource* resource) { | 157 void GrResourceCache::removeResource(GrGpuResource* resource) { |
| 157 this->validate(); | 158 this->validate(); |
| 158 SkASSERT(this->isInCache(resource)); | 159 SkASSERT(this->isInCache(resource)); |
| 159 | 160 |
| 160 if (resource->isPurgeable()) { | 161 if (resource->isPurgeable()) { |
| 161 fPurgeableQueue.remove(resource); | 162 fPurgeableQueue.remove(resource); |
| 162 } else { | 163 } else { |
| 163 this->removeFromNonpurgeableArray(resource); | 164 this->removeFromNonpurgeableArray(resource); |
| 164 } | 165 } |
| 165 | 166 |
| 166 size_t size = resource->gpuMemorySize(); | 167 size_t size = resource->gpuMemorySize(); |
| 167 SkDEBUGCODE(--fCount;) | 168 SkDEBUGCODE(--fCount;) |
| 168 fBytes -= size; | 169 fBytes -= size; |
| 169 if (SkBudgeted::kYes == resource->resourcePriv().isBudgeted()) { | 170 if (SkBudgeted::kYes == resource->resourcePriv().isBudgeted()) { |
| 170 --fBudgetedCount; | 171 --fBudgetedCount; |
| 171 fBudgetedBytes -= size; | 172 fBudgetedBytes -= size; |
| 172 TRACE_COUNTER2(TRACE_DISABLED_BY_DEFAULT("skia.gpu.cache"), "skia budget
", "used", | 173 TRACE_COUNTER2(TRACE_DISABLED_BY_DEFAULT("skia.gpu.cache"), "skia budget
", "used", |
| 173 fBudgetedBytes, "free", fMaxBytes - fBudgetedBytes); | 174 fBudgetedBytes, "free", fMaxBytes - fBudgetedBytes); |
| 174 } | 175 } |
| 175 | 176 |
| 176 if (resource->resourcePriv().getScratchKey().isValid()) { | 177 if (resource->resourcePriv().getScratchKey().isValid() && |
| 178 !resource->getUniqueKey().isValid()) { |
| 177 fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); | 179 fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); |
| 178 } | 180 } |
| 179 if (resource->getUniqueKey().isValid()) { | 181 if (resource->getUniqueKey().isValid()) { |
| 180 fUniqueHash.remove(resource->getUniqueKey()); | 182 fUniqueHash.remove(resource->getUniqueKey()); |
| 181 } | 183 } |
| 182 this->validate(); | 184 this->validate(); |
| 183 } | 185 } |
| 184 | 186 |
| 185 void GrResourceCache::abandonAll() { | 187 void GrResourceCache::abandonAll() { |
| 186 AutoValidate av(this); | 188 AutoValidate av(this); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 SkASSERT(!fBytes); | 230 SkASSERT(!fBytes); |
| 229 SkASSERT(!fBudgetedCount); | 231 SkASSERT(!fBudgetedCount); |
| 230 SkASSERT(!fBudgetedBytes); | 232 SkASSERT(!fBudgetedBytes); |
| 231 } | 233 } |
| 232 | 234 |
| 233 class GrResourceCache::AvailableForScratchUse { | 235 class GrResourceCache::AvailableForScratchUse { |
| 234 public: | 236 public: |
| 235 AvailableForScratchUse(bool rejectPendingIO) : fRejectPendingIO(rejectPendin
gIO) { } | 237 AvailableForScratchUse(bool rejectPendingIO) : fRejectPendingIO(rejectPendin
gIO) { } |
| 236 | 238 |
| 237 bool operator()(const GrGpuResource* resource) const { | 239 bool operator()(const GrGpuResource* resource) const { |
| 240 SkASSERT(!resource->getUniqueKey().isValid() && |
| 241 resource->resourcePriv().getScratchKey().isValid()); |
| 238 if (resource->internalHasRef() || !resource->cacheAccess().isScratch())
{ | 242 if (resource->internalHasRef() || !resource->cacheAccess().isScratch())
{ |
| 239 return false; | 243 return false; |
| 240 } | 244 } |
| 241 return !fRejectPendingIO || !resource->internalHasPendingIO(); | 245 return !fRejectPendingIO || !resource->internalHasPendingIO(); |
| 242 } | 246 } |
| 243 | 247 |
| 244 private: | 248 private: |
| 245 bool fRejectPendingIO; | 249 bool fRejectPendingIO; |
| 246 }; | 250 }; |
| 247 | 251 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 272 resource = fScratchMap.find(scratchKey, AvailableForScratchUse(false)); | 276 resource = fScratchMap.find(scratchKey, AvailableForScratchUse(false)); |
| 273 if (resource) { | 277 if (resource) { |
| 274 this->refAndMakeResourceMRU(resource); | 278 this->refAndMakeResourceMRU(resource); |
| 275 this->validate(); | 279 this->validate(); |
| 276 } | 280 } |
| 277 return resource; | 281 return resource; |
| 278 } | 282 } |
| 279 | 283 |
| 280 void GrResourceCache::willRemoveScratchKey(const GrGpuResource* resource) { | 284 void GrResourceCache::willRemoveScratchKey(const GrGpuResource* resource) { |
| 281 SkASSERT(resource->resourcePriv().getScratchKey().isValid()); | 285 SkASSERT(resource->resourcePriv().getScratchKey().isValid()); |
| 282 fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); | 286 if (!resource->getUniqueKey().isValid()) { |
| 287 fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); |
| 288 } |
| 283 } | 289 } |
| 284 | 290 |
| 285 void GrResourceCache::removeUniqueKey(GrGpuResource* resource) { | 291 void GrResourceCache::removeUniqueKey(GrGpuResource* resource) { |
| 286 // Someone has a ref to this resource in order to have removed the key. When
the ref count | 292 // Someone has a ref to this resource in order to have removed the key. When
the ref count |
| 287 // reaches zero we will get a ref cnt notification and figure out what to do
with it. | 293 // reaches zero we will get a ref cnt notification and figure out what to do
with it. |
| 288 if (resource->getUniqueKey().isValid()) { | 294 if (resource->getUniqueKey().isValid()) { |
| 289 SkASSERT(resource == fUniqueHash.find(resource->getUniqueKey())); | 295 SkASSERT(resource == fUniqueHash.find(resource->getUniqueKey())); |
| 290 fUniqueHash.remove(resource->getUniqueKey()); | 296 fUniqueHash.remove(resource->getUniqueKey()); |
| 291 } | 297 } |
| 292 resource->cacheAccess().removeUniqueKey(); | 298 resource->cacheAccess().removeUniqueKey(); |
| 299 |
| 300 if (resource->resourcePriv().getScratchKey().isValid()) { |
| 301 fScratchMap.insert(resource->resourcePriv().getScratchKey(), resource); |
| 302 } |
| 303 |
| 293 this->validate(); | 304 this->validate(); |
| 294 } | 305 } |
| 295 | 306 |
| 296 void GrResourceCache::changeUniqueKey(GrGpuResource* resource, const GrUniqueKey
& newKey) { | 307 void GrResourceCache::changeUniqueKey(GrGpuResource* resource, const GrUniqueKey
& newKey) { |
| 297 SkASSERT(resource); | 308 SkASSERT(resource); |
| 298 SkASSERT(this->isInCache(resource)); | 309 SkASSERT(this->isInCache(resource)); |
| 299 | 310 |
| 300 // Remove the entry for this resource if it already has a unique key. | |
| 301 if (resource->getUniqueKey().isValid()) { | |
| 302 SkASSERT(resource == fUniqueHash.find(resource->getUniqueKey())); | |
| 303 fUniqueHash.remove(resource->getUniqueKey()); | |
| 304 SkASSERT(nullptr == fUniqueHash.find(resource->getUniqueKey())); | |
| 305 } | |
| 306 | |
| 307 // If another resource has the new key, remove its key then install the key
on this resource. | 311 // If another resource has the new key, remove its key then install the key
on this resource. |
| 308 if (newKey.isValid()) { | 312 if (newKey.isValid()) { |
| 313 // Remove the entry for this resource if it already has a unique key. |
| 314 if (resource->getUniqueKey().isValid()) { |
| 315 SkASSERT(resource == fUniqueHash.find(resource->getUniqueKey())); |
| 316 fUniqueHash.remove(resource->getUniqueKey()); |
| 317 SkASSERT(nullptr == fUniqueHash.find(resource->getUniqueKey())); |
| 318 } else { |
| 319 // 'resource' didn't have a valid unique key before so it is switchi
ng sides. Remove it |
| 320 // from the ScratchMap |
| 321 if (resource->resourcePriv().getScratchKey().isValid()) { |
| 322 fScratchMap.remove(resource->resourcePriv().getScratchKey(), res
ource); |
| 323 } |
| 324 } |
| 325 |
| 309 if (GrGpuResource* old = fUniqueHash.find(newKey)) { | 326 if (GrGpuResource* old = fUniqueHash.find(newKey)) { |
| 310 // If the old resource using the key is purgeable and is unreachable
, then remove it. | 327 // If the old resource using the key is purgeable and is unreachable
, then remove it. |
| 311 if (!old->resourcePriv().getScratchKey().isValid() && old->isPurgeab
le()) { | 328 if (!old->resourcePriv().getScratchKey().isValid() && old->isPurgeab
le()) { |
| 312 // release may call validate() which will assert that resource i
s in fUniqueHash | 329 // release may call validate() which will assert that resource i
s in fUniqueHash |
| 313 // if it has a valid key. So in debug reset the key here before
we assign it. | 330 // if it has a valid key. So in debug reset the key here before
we assign it. |
| 314 SkDEBUGCODE(resource->cacheAccess().removeUniqueKey();) | 331 SkDEBUGCODE(resource->cacheAccess().removeUniqueKey();) |
| 315 old->cacheAccess().release(); | 332 old->cacheAccess().release(); |
| 316 } else { | 333 } else { |
| 317 fUniqueHash.remove(newKey); | 334 this->removeUniqueKey(old); |
| 318 old->cacheAccess().removeUniqueKey(); | |
| 319 } | 335 } |
| 320 } | 336 } |
| 321 SkASSERT(nullptr == fUniqueHash.find(newKey)); | 337 SkASSERT(nullptr == fUniqueHash.find(newKey)); |
| 322 resource->cacheAccess().setUniqueKey(newKey); | 338 resource->cacheAccess().setUniqueKey(newKey); |
| 323 fUniqueHash.add(resource); | 339 fUniqueHash.add(resource); |
| 324 } else { | 340 } else { |
| 325 resource->cacheAccess().removeUniqueKey(); | 341 this->removeUniqueKey(resource); |
| 326 } | 342 } |
| 327 | 343 |
| 328 this->validate(); | 344 this->validate(); |
| 329 } | 345 } |
| 330 | 346 |
| 331 void GrResourceCache::refAndMakeResourceMRU(GrGpuResource* resource) { | 347 void GrResourceCache::refAndMakeResourceMRU(GrGpuResource* resource) { |
| 332 SkASSERT(resource); | 348 SkASSERT(resource); |
| 333 SkASSERT(this->isInCache(resource)); | 349 SkASSERT(this->isInCache(resource)); |
| 334 | 350 |
| 335 if (resource->isPurgeable()) { | 351 if (resource->isPurgeable()) { |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 fUniqueHash = &cache->fUniqueHash; | 666 fUniqueHash = &cache->fUniqueHash; |
| 651 } | 667 } |
| 652 | 668 |
| 653 void update(GrGpuResource* resource) { | 669 void update(GrGpuResource* resource) { |
| 654 fBytes += resource->gpuMemorySize(); | 670 fBytes += resource->gpuMemorySize(); |
| 655 | 671 |
| 656 if (!resource->isPurgeable()) { | 672 if (!resource->isPurgeable()) { |
| 657 ++fLocked; | 673 ++fLocked; |
| 658 } | 674 } |
| 659 | 675 |
| 676 const GrScratchKey& scratchKey = resource->resourcePriv().getScratch
Key(); |
| 677 const GrUniqueKey& uniqueKey = resource->getUniqueKey(); |
| 678 |
| 660 if (resource->cacheAccess().isScratch()) { | 679 if (resource->cacheAccess().isScratch()) { |
| 661 SkASSERT(!resource->getUniqueKey().isValid()); | 680 SkASSERT(!uniqueKey.isValid()); |
| 662 ++fScratch; | 681 ++fScratch; |
| 663 SkASSERT(fScratchMap->countForKey(resource->resourcePriv().getSc
ratchKey())); | 682 SkASSERT(fScratchMap->countForKey(scratchKey)); |
| 664 SkASSERT(!resource->resourcePriv().refsWrappedObjects()); | 683 SkASSERT(!resource->resourcePriv().refsWrappedObjects()); |
| 665 } else if (resource->resourcePriv().getScratchKey().isValid()) { | 684 } else if (scratchKey.isValid()) { |
| 666 SkASSERT(SkBudgeted::kNo == resource->resourcePriv().isBudgeted(
) || | 685 SkASSERT(SkBudgeted::kNo == resource->resourcePriv().isBudgeted(
) || |
| 667 resource->getUniqueKey().isValid()); | 686 uniqueKey.isValid()); |
| 668 ++fCouldBeScratch; | 687 if (!uniqueKey.isValid()) { |
| 669 SkASSERT(fScratchMap->countForKey(resource->resourcePriv().getSc
ratchKey())); | 688 ++fCouldBeScratch; |
| 689 SkASSERT(fScratchMap->countForKey(scratchKey)); |
| 690 } |
| 670 SkASSERT(!resource->resourcePriv().refsWrappedObjects()); | 691 SkASSERT(!resource->resourcePriv().refsWrappedObjects()); |
| 671 } | 692 } |
| 672 const GrUniqueKey& uniqueKey = resource->getUniqueKey(); | |
| 673 if (uniqueKey.isValid()) { | 693 if (uniqueKey.isValid()) { |
| 674 ++fContent; | 694 ++fContent; |
| 675 SkASSERT(fUniqueHash->find(uniqueKey) == resource); | 695 SkASSERT(fUniqueHash->find(uniqueKey) == resource); |
| 676 SkASSERT(!resource->resourcePriv().refsWrappedObjects()); | 696 SkASSERT(!resource->resourcePriv().refsWrappedObjects()); |
| 677 SkASSERT(SkBudgeted::kYes == resource->resourcePriv().isBudgeted
()); | 697 SkASSERT(SkBudgeted::kYes == resource->resourcePriv().isBudgeted
()); |
| 698 |
| 699 if (scratchKey.isValid()) { |
| 700 SkASSERT(!fScratchMap->has(resource, scratchKey)); |
| 701 } |
| 678 } | 702 } |
| 679 | 703 |
| 680 if (SkBudgeted::kYes == resource->resourcePriv().isBudgeted()) { | 704 if (SkBudgeted::kYes == resource->resourcePriv().isBudgeted()) { |
| 681 ++fBudgetedCount; | 705 ++fBudgetedCount; |
| 682 fBudgetedBytes += resource->gpuMemorySize(); | 706 fBudgetedBytes += resource->gpuMemorySize(); |
| 683 } | 707 } |
| 684 } | 708 } |
| 685 }; | 709 }; |
| 686 | 710 |
| 711 { |
| 712 ScratchMap::ConstIter iter(&fScratchMap); |
| 713 |
| 714 int count = 0; |
| 715 for ( ; !iter.done(); ++iter) { |
| 716 const GrGpuResource* resource = *iter; |
| 717 SkASSERT(resource->resourcePriv().getScratchKey().isValid()); |
| 718 SkASSERT(!resource->getUniqueKey().isValid()); |
| 719 count++; |
| 720 } |
| 721 SkASSERT(count == fScratchMap.count()); // ensure the iterator is workin
g correctly |
| 722 } |
| 723 |
| 687 Stats stats(this); | 724 Stats stats(this); |
| 688 | 725 |
| 689 for (int i = 0; i < fNonpurgeableResources.count(); ++i) { | 726 for (int i = 0; i < fNonpurgeableResources.count(); ++i) { |
| 690 SkASSERT(!fNonpurgeableResources[i]->isPurgeable() || | 727 SkASSERT(!fNonpurgeableResources[i]->isPurgeable() || |
| 691 fNewlyPurgeableResourceForValidation == fNonpurgeableResources[
i]); | 728 fNewlyPurgeableResourceForValidation == fNonpurgeableResources[
i]); |
| 692 SkASSERT(*fNonpurgeableResources[i]->cacheAccess().accessCacheIndex() ==
i); | 729 SkASSERT(*fNonpurgeableResources[i]->cacheAccess().accessCacheIndex() ==
i); |
| 693 SkASSERT(!fNonpurgeableResources[i]->wasDestroyed()); | 730 SkASSERT(!fNonpurgeableResources[i]->wasDestroyed()); |
| 694 stats.update(fNonpurgeableResources[i]); | 731 stats.update(fNonpurgeableResources[i]); |
| 695 } | 732 } |
| 696 for (int i = 0; i < fPurgeableQueue.count(); ++i) { | 733 for (int i = 0; i < fPurgeableQueue.count(); ++i) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 return true; | 769 return true; |
| 733 } | 770 } |
| 734 if (index < fNonpurgeableResources.count() && fNonpurgeableResources[index]
== resource) { | 771 if (index < fNonpurgeableResources.count() && fNonpurgeableResources[index]
== resource) { |
| 735 return true; | 772 return true; |
| 736 } | 773 } |
| 737 SkDEBUGFAIL("Resource index should be -1 or the resource should be in the ca
che."); | 774 SkDEBUGFAIL("Resource index should be -1 or the resource should be in the ca
che."); |
| 738 return false; | 775 return false; |
| 739 } | 776 } |
| 740 | 777 |
| 741 #endif | 778 #endif |
| OLD | NEW |