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 |