OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2014 Google Inc. | 3 * Copyright 2014 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "GrResourceCache.h" | 10 #include "GrResourceCache.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 GrUniqueKey::Domain GrUniqueKey::GenerateDomain() { | 33 GrUniqueKey::Domain GrUniqueKey::GenerateDomain() { |
34 static int32_t gDomain = INHERITED::kInvalidDomain + 1; | 34 static int32_t gDomain = INHERITED::kInvalidDomain + 1; |
35 | 35 |
36 int32_t domain = sk_atomic_inc(&gDomain); | 36 int32_t domain = sk_atomic_inc(&gDomain); |
37 if (domain > SK_MaxU16) { | 37 if (domain > SK_MaxU16) { |
38 SkFAIL("Too many GrUniqueKey Domains"); | 38 SkFAIL("Too many GrUniqueKey Domains"); |
39 } | 39 } |
40 | 40 |
41 return static_cast<Domain>(domain); | 41 return static_cast<Domain>(domain); |
42 } | 42 } |
| 43 |
43 uint32_t GrResourceKeyHash(const uint32_t* data, size_t size) { | 44 uint32_t GrResourceKeyHash(const uint32_t* data, size_t size) { |
44 return SkChecksum::Compute(data, size); | 45 return SkChecksum::Compute(data, size); |
45 } | 46 } |
46 | 47 |
47 ////////////////////////////////////////////////////////////////////////////// | 48 ////////////////////////////////////////////////////////////////////////////// |
48 | 49 |
49 class GrResourceCache::AutoValidate : ::SkNoncopyable { | 50 class GrResourceCache::AutoValidate : ::SkNoncopyable { |
50 public: | 51 public: |
51 AutoValidate(GrResourceCache* cache) : fCache(cache) { cache->validate(); } | 52 AutoValidate(GrResourceCache* cache) : fCache(cache) { cache->validate(); } |
52 ~AutoValidate() { fCache->validate(); } | 53 ~AutoValidate() { fCache->validate(); } |
53 private: | 54 private: |
54 GrResourceCache* fCache; | 55 GrResourceCache* fCache; |
55 }; | 56 }; |
56 | 57 |
57 ////////////////////////////////////////////////////////////////////////////// | 58 ////////////////////////////////////////////////////////////////////////////// |
58 | 59 |
59 static const int kDefaultMaxCount = 2 * (1 << 12); | |
60 static const size_t kDefaultMaxSize = 96 * (1 << 20); | |
61 | 60 |
62 GrResourceCache::GrResourceCache() | 61 GrResourceCache::GrResourceCache() |
63 : fTimestamp(0) | 62 : fTimestamp(0) |
64 , fMaxCount(kDefaultMaxCount) | 63 , fMaxCount(kDefaultMaxCount) |
65 , fMaxBytes(kDefaultMaxSize) | 64 , fMaxBytes(kDefaultMaxSize) |
| 65 , fMaxUnusedFlushes(kDefaultMaxUnusedFlushes) |
66 #if GR_CACHE_STATS | 66 #if GR_CACHE_STATS |
67 , fHighWaterCount(0) | 67 , fHighWaterCount(0) |
68 , fHighWaterBytes(0) | 68 , fHighWaterBytes(0) |
69 , fBudgetedHighWaterCount(0) | 69 , fBudgetedHighWaterCount(0) |
70 , fBudgetedHighWaterBytes(0) | 70 , fBudgetedHighWaterBytes(0) |
71 #endif | 71 #endif |
72 , fBytes(0) | 72 , fBytes(0) |
73 , fBudgetedCount(0) | 73 , fBudgetedCount(0) |
74 , fBudgetedBytes(0) | 74 , fBudgetedBytes(0) |
75 , fOverBudgetCB(NULL) | 75 , fOverBudgetCB(NULL) |
76 , fOverBudgetData(NULL) { | 76 , fOverBudgetData(NULL) |
| 77 , fFlushTimestamps(NULL) |
| 78 , fLastFlushTimestampIndex(0){ |
77 SkDEBUGCODE(fCount = 0;) | 79 SkDEBUGCODE(fCount = 0;) |
| 80 SkDEBUGCODE(fNewlyPurgeableResourceForValidation = NULL;) |
| 81 this->resetFlushTimestamps(); |
78 } | 82 } |
79 | 83 |
80 GrResourceCache::~GrResourceCache() { | 84 GrResourceCache::~GrResourceCache() { |
81 this->releaseAll(); | 85 this->releaseAll(); |
| 86 SkDELETE(fFlushTimestamps); |
82 } | 87 } |
83 | 88 |
84 void GrResourceCache::setLimits(int count, size_t bytes) { | 89 void GrResourceCache::setLimits(int count, size_t bytes, int maxUnusedFlushes) { |
85 fMaxCount = count; | 90 fMaxCount = count; |
86 fMaxBytes = bytes; | 91 fMaxBytes = bytes; |
| 92 fMaxUnusedFlushes = maxUnusedFlushes; |
| 93 this->resetFlushTimestamps(); |
87 this->purgeAsNeeded(); | 94 this->purgeAsNeeded(); |
88 } | 95 } |
89 | 96 |
| 97 void GrResourceCache::resetFlushTimestamps() { |
| 98 SkDELETE(fFlushTimestamps); |
| 99 |
| 100 // We assume this number is a power of two when wrapping indices into the ti
mestamp array. |
| 101 fMaxUnusedFlushes = SkNextPow2(fMaxUnusedFlushes); |
| 102 |
| 103 // Since our implementation is to store the timestamps of the last fMaxUnuse
dFlushes flush calls |
| 104 // we just turn the feature off if that array would be large. |
| 105 static const int kMaxSupportedTimestampHistory = 128; |
| 106 |
| 107 if (fMaxUnusedFlushes > kMaxSupportedTimestampHistory) { |
| 108 fFlushTimestamps = NULL; |
| 109 return; |
| 110 } |
| 111 |
| 112 fFlushTimestamps = SkNEW_ARRAY(uint32_t, fMaxUnusedFlushes); |
| 113 fLastFlushTimestampIndex = 0; |
| 114 // Set all the historical flush timestamps to initially be at the beginning
of time (timestamp |
| 115 // 0). |
| 116 sk_bzero(fFlushTimestamps, fMaxUnusedFlushes * sizeof(uint32_t)); |
| 117 } |
| 118 |
90 void GrResourceCache::insertResource(GrGpuResource* resource) { | 119 void GrResourceCache::insertResource(GrGpuResource* resource) { |
91 SkASSERT(resource); | 120 SkASSERT(resource); |
92 SkASSERT(!this->isInCache(resource)); | 121 SkASSERT(!this->isInCache(resource)); |
93 SkASSERT(!resource->wasDestroyed()); | 122 SkASSERT(!resource->wasDestroyed()); |
94 SkASSERT(!resource->isPurgeable()); | 123 SkASSERT(!resource->isPurgeable()); |
95 | 124 |
96 // We must set the timestamp before adding to the array in case the timestam
p wraps and we wind | 125 // We must set the timestamp before adding to the array in case the timestam
p wraps and we wind |
97 // up iterating over all the resources that already have timestamps. | 126 // up iterating over all the resources that already have timestamps. |
98 resource->cacheAccess().setTimestamp(this->getNextTimestamp()); | 127 resource->cacheAccess().setTimestamp(this->getNextTimestamp()); |
99 | 128 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 } | 269 } |
241 return resource; | 270 return resource; |
242 } | 271 } |
243 | 272 |
244 void GrResourceCache::willRemoveScratchKey(const GrGpuResource* resource) { | 273 void GrResourceCache::willRemoveScratchKey(const GrGpuResource* resource) { |
245 SkASSERT(resource->resourcePriv().getScratchKey().isValid()); | 274 SkASSERT(resource->resourcePriv().getScratchKey().isValid()); |
246 fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); | 275 fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); |
247 } | 276 } |
248 | 277 |
249 void GrResourceCache::removeUniqueKey(GrGpuResource* resource) { | 278 void GrResourceCache::removeUniqueKey(GrGpuResource* resource) { |
250 // Someone has a ref to this resource in order to invalidate it. When the re
f count reaches | 279 // Someone has a ref to this resource in order to have removed the key. When
the ref count |
251 // zero we will get a notifyPurgable() and figure out what to do with it. | 280 // reaches zero we will get a ref cnt notification and figure out what to do
with it. |
252 if (resource->getUniqueKey().isValid()) { | 281 if (resource->getUniqueKey().isValid()) { |
253 SkASSERT(resource == fUniqueHash.find(resource->getUniqueKey())); | 282 SkASSERT(resource == fUniqueHash.find(resource->getUniqueKey())); |
254 fUniqueHash.remove(resource->getUniqueKey()); | 283 fUniqueHash.remove(resource->getUniqueKey()); |
255 } | 284 } |
256 resource->cacheAccess().removeUniqueKey(); | 285 resource->cacheAccess().removeUniqueKey(); |
257 this->validate(); | 286 this->validate(); |
258 } | 287 } |
259 | 288 |
260 void GrResourceCache::changeUniqueKey(GrGpuResource* resource, const GrUniqueKey
& newKey) { | 289 void GrResourceCache::changeUniqueKey(GrGpuResource* resource, const GrUniqueKey
& newKey) { |
261 SkASSERT(resource); | 290 SkASSERT(resource); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 // It's about to become unpurgeable. | 329 // It's about to become unpurgeable. |
301 fPurgeableQueue.remove(resource); | 330 fPurgeableQueue.remove(resource); |
302 this->addToNonpurgeableArray(resource); | 331 this->addToNonpurgeableArray(resource); |
303 } | 332 } |
304 resource->ref(); | 333 resource->ref(); |
305 | 334 |
306 resource->cacheAccess().setTimestamp(this->getNextTimestamp()); | 335 resource->cacheAccess().setTimestamp(this->getNextTimestamp()); |
307 this->validate(); | 336 this->validate(); |
308 } | 337 } |
309 | 338 |
310 void GrResourceCache::notifyPurgeable(GrGpuResource* resource) { | 339 void GrResourceCache::notifyCntReachedZero(GrGpuResource* resource, uint32_t fla
gs) { |
311 SkASSERT(resource); | 340 SkASSERT(resource); |
| 341 SkASSERT(!resource->wasDestroyed()); |
| 342 SkASSERT(flags); |
312 SkASSERT(this->isInCache(resource)); | 343 SkASSERT(this->isInCache(resource)); |
| 344 // This resource should always be in the nonpurgeable array when this functi
on is called. It |
| 345 // will be moved to the queue if it is newly purgeable. |
| 346 SkASSERT(fNonpurgeableResources[*resource->cacheAccess().accessCacheIndex()]
== resource); |
| 347 |
| 348 if (SkToBool(ResourceAccess::kRefCntReachedZero_RefNotificationFlag & flags)
) { |
| 349 #ifdef SK_DEBUG |
| 350 // When the timestamp overflows validate() is called. validate() checks
that resources in |
| 351 // the nonpurgeable array are indeed not purgeable. However, the movemen
t from the array to |
| 352 // the purgeable queue happens just below in this function. So we mark i
t as an exception. |
| 353 if (resource->isPurgeable()) { |
| 354 fNewlyPurgeableResourceForValidation = resource; |
| 355 } |
| 356 #endif |
| 357 resource->cacheAccess().setTimestamp(this->getNextTimestamp()); |
| 358 SkDEBUGCODE(fNewlyPurgeableResourceForValidation = NULL); |
| 359 } |
| 360 |
| 361 if (!SkToBool(ResourceAccess::kAllCntsReachedZero_RefNotificationFlag & flag
s)) { |
| 362 SkASSERT(!resource->isPurgeable()); |
| 363 return; |
| 364 } |
| 365 |
313 SkASSERT(resource->isPurgeable()); | 366 SkASSERT(resource->isPurgeable()); |
314 | |
315 this->removeFromNonpurgeableArray(resource); | 367 this->removeFromNonpurgeableArray(resource); |
316 fPurgeableQueue.insert(resource); | 368 fPurgeableQueue.insert(resource); |
317 | 369 |
318 if (!resource->resourcePriv().isBudgeted()) { | 370 if (!resource->resourcePriv().isBudgeted()) { |
319 // Check whether this resource could still be used as a scratch resource
. | 371 // Check whether this resource could still be used as a scratch resource
. |
320 if (!resource->cacheAccess().isWrapped() && | 372 if (!resource->cacheAccess().isWrapped() && |
321 resource->resourcePriv().getScratchKey().isValid()) { | 373 resource->resourcePriv().getScratchKey().isValid()) { |
322 // We won't purge an existing resource to make room for this one. | 374 // We won't purge an existing resource to make room for this one. |
323 if (fBudgetedCount < fMaxCount && | 375 if (fBudgetedCount < fMaxCount && |
324 fBudgetedBytes + resource->gpuMemorySize() <= fMaxBytes) { | 376 fBudgetedBytes + resource->gpuMemorySize() <= fMaxBytes) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 } else { | 436 } else { |
385 --fBudgetedCount; | 437 --fBudgetedCount; |
386 fBudgetedBytes -= size; | 438 fBudgetedBytes -= size; |
387 } | 439 } |
388 TRACE_COUNTER2(TRACE_DISABLED_BY_DEFAULT("skia.gpu.cache"), "skia budget", "
used", | 440 TRACE_COUNTER2(TRACE_DISABLED_BY_DEFAULT("skia.gpu.cache"), "skia budget", "
used", |
389 fBudgetedBytes, "free", fMaxBytes - fBudgetedBytes); | 441 fBudgetedBytes, "free", fMaxBytes - fBudgetedBytes); |
390 | 442 |
391 this->validate(); | 443 this->validate(); |
392 } | 444 } |
393 | 445 |
394 void GrResourceCache::internalPurgeAsNeeded() { | 446 void GrResourceCache::purgeAsNeeded() { |
395 SkASSERT(this->overBudget()); | 447 SkTArray<GrUniqueKeyInvalidatedMessage> invalidKeyMsgs; |
| 448 fInvalidUniqueKeyInbox.poll(&invalidKeyMsgs); |
| 449 if (invalidKeyMsgs.count()) { |
| 450 this->processInvalidUniqueKeys(invalidKeyMsgs); |
| 451 } |
396 | 452 |
397 bool stillOverbudget = true; | 453 if (fFlushTimestamps) { |
398 while (fPurgeableQueue.count()) { | 454 // Assuming kNumFlushesToDeleteUnusedResource is a power of 2. |
| 455 SkASSERT(SkIsPow2(fMaxUnusedFlushes)); |
| 456 int oldestFlushIndex = (fLastFlushTimestampIndex + 1) & (fMaxUnusedFlush
es - 1); |
| 457 |
| 458 uint32_t oldestAllowedTimestamp = fFlushTimestamps[oldestFlushIndex]; |
| 459 while (fPurgeableQueue.count()) { |
| 460 uint32_t oldestResourceTimestamp = fPurgeableQueue.peek()->cacheAcce
ss().timestamp(); |
| 461 if (oldestAllowedTimestamp < oldestResourceTimestamp) { |
| 462 break; |
| 463 } |
| 464 GrGpuResource* resource = fPurgeableQueue.peek(); |
| 465 SkASSERT(resource->isPurgeable()); |
| 466 resource->cacheAccess().release(); |
| 467 } |
| 468 } |
| 469 |
| 470 bool stillOverbudget = this->overBudget(); |
| 471 while (stillOverbudget && fPurgeableQueue.count()) { |
399 GrGpuResource* resource = fPurgeableQueue.peek(); | 472 GrGpuResource* resource = fPurgeableQueue.peek(); |
400 SkASSERT(resource->isPurgeable()); | 473 SkASSERT(resource->isPurgeable()); |
401 resource->cacheAccess().release(); | 474 resource->cacheAccess().release(); |
402 if (!this->overBudget()) { | 475 stillOverbudget = this->overBudget(); |
403 stillOverbudget = false; | |
404 break; | |
405 } | |
406 } | 476 } |
407 | 477 |
408 this->validate(); | 478 this->validate(); |
409 | 479 |
410 if (stillOverbudget) { | 480 if (stillOverbudget) { |
411 // Despite the purge we're still over budget. Call our over budget callb
ack. If this frees | 481 // Despite the purge we're still over budget. Call our over budget callb
ack. If this frees |
412 // any resources then we'll get notifyPurgeable() calls and take appropr
iate action. | 482 // any resources then we'll get notified and take appropriate action. |
413 (*fOverBudgetCB)(fOverBudgetData); | 483 (*fOverBudgetCB)(fOverBudgetData); |
414 this->validate(); | 484 this->validate(); |
415 } | 485 } |
416 } | 486 } |
417 | 487 |
418 void GrResourceCache::purgeAllUnlocked() { | 488 void GrResourceCache::purgeAllUnlocked() { |
419 // We could disable maintaining the heap property here, but it would add a l
ot of complexity. | 489 // We could disable maintaining the heap property here, but it would add a l
ot of complexity. |
420 // Moreover, this is rarely called. | 490 // Moreover, this is rarely called. |
421 while (fPurgeableQueue.count()) { | 491 while (fPurgeableQueue.count()) { |
422 GrGpuResource* resource = fPurgeableQueue.peek(); | 492 GrGpuResource* resource = fPurgeableQueue.peek(); |
423 SkASSERT(resource->isPurgeable()); | 493 SkASSERT(resource->isPurgeable()); |
424 resource->cacheAccess().release(); | 494 resource->cacheAccess().release(); |
425 } | 495 } |
426 | 496 |
427 this->validate(); | 497 this->validate(); |
428 } | 498 } |
429 | 499 |
430 void GrResourceCache::processInvalidUniqueKeys( | 500 void GrResourceCache::processInvalidUniqueKeys( |
431 const SkTArray<GrUniqueKeyInvalidatedMessage>& msgs) { | 501 const SkTArray<GrUniqueKeyInvalidatedMessage>& msgs) { |
432 for (int i = 0; i < msgs.count(); ++i) { | 502 for (int i = 0; i < msgs.count(); ++i) { |
433 GrGpuResource* resource = this->findAndRefUniqueResource(msgs[i].key()); | 503 GrGpuResource* resource = this->findAndRefUniqueResource(msgs[i].key()); |
434 if (resource) { | 504 if (resource) { |
435 resource->resourcePriv().removeUniqueKey(); | 505 resource->resourcePriv().removeUniqueKey(); |
436 resource->unref(); // will call notifyPurgeable, if it is indeed now
purgeable. | 506 resource->unref(); // If this resource is now purgeable, the cache w
ill be notified. |
437 } | 507 } |
438 } | 508 } |
439 } | 509 } |
440 | 510 |
441 void GrResourceCache::addToNonpurgeableArray(GrGpuResource* resource) { | 511 void GrResourceCache::addToNonpurgeableArray(GrGpuResource* resource) { |
442 int index = fNonpurgeableResources.count(); | 512 int index = fNonpurgeableResources.count(); |
443 *fNonpurgeableResources.append() = resource; | 513 *fNonpurgeableResources.append() = resource; |
444 *resource->cacheAccess().accessCacheIndex() = index; | 514 *resource->cacheAccess().accessCacheIndex() = index; |
445 } | 515 } |
446 | 516 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 // Rebuild the queue. | 581 // Rebuild the queue. |
512 for (int i = 0; i < sortedPurgeableResources.count(); ++i) { | 582 for (int i = 0; i < sortedPurgeableResources.count(); ++i) { |
513 fPurgeableQueue.insert(sortedPurgeableResources[i]); | 583 fPurgeableQueue.insert(sortedPurgeableResources[i]); |
514 } | 584 } |
515 | 585 |
516 this->validate(); | 586 this->validate(); |
517 SkASSERT(count == this->getResourceCount()); | 587 SkASSERT(count == this->getResourceCount()); |
518 | 588 |
519 // count should be the next timestamp we return. | 589 // count should be the next timestamp we return. |
520 SkASSERT(fTimestamp == SkToU32(count)); | 590 SkASSERT(fTimestamp == SkToU32(count)); |
| 591 |
| 592 // The historical timestamps of flushes are now invalid. |
| 593 this->resetFlushTimestamps(); |
521 } | 594 } |
522 } | 595 } |
523 return fTimestamp++; | 596 return fTimestamp++; |
524 } | 597 } |
525 | 598 |
| 599 void GrResourceCache::notifyFlushOccurred() { |
| 600 if (fFlushTimestamps) { |
| 601 SkASSERT(SkIsPow2(fMaxUnusedFlushes)); |
| 602 fLastFlushTimestampIndex = (fLastFlushTimestampIndex + 1) & (fMaxUnusedF
lushes - 1); |
| 603 // get the timestamp before accessing fFlushTimestamps because getNextTi
mestamp will |
| 604 // reallocate fFlushTimestamps on timestamp overflow. |
| 605 uint32_t timestamp = this->getNextTimestamp(); |
| 606 fFlushTimestamps[fLastFlushTimestampIndex] = timestamp; |
| 607 this->purgeAsNeeded(); |
| 608 } |
| 609 } |
| 610 |
526 #ifdef SK_DEBUG | 611 #ifdef SK_DEBUG |
527 void GrResourceCache::validate() const { | 612 void GrResourceCache::validate() const { |
528 // Reduce the frequency of validations for large resource counts. | 613 // Reduce the frequency of validations for large resource counts. |
529 static SkRandom gRandom; | 614 static SkRandom gRandom; |
530 int mask = (SkNextPow2(fCount + 1) >> 5) - 1; | 615 int mask = (SkNextPow2(fCount + 1) >> 5) - 1; |
531 if (~mask && (gRandom.nextU() & mask)) { | 616 if (~mask && (gRandom.nextU() & mask)) { |
532 return; | 617 return; |
533 } | 618 } |
534 | 619 |
535 struct Stats { | 620 struct Stats { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 if (resource->resourcePriv().isBudgeted()) { | 664 if (resource->resourcePriv().isBudgeted()) { |
580 ++fBudgetedCount; | 665 ++fBudgetedCount; |
581 fBudgetedBytes += resource->gpuMemorySize(); | 666 fBudgetedBytes += resource->gpuMemorySize(); |
582 } | 667 } |
583 } | 668 } |
584 }; | 669 }; |
585 | 670 |
586 Stats stats(this); | 671 Stats stats(this); |
587 | 672 |
588 for (int i = 0; i < fNonpurgeableResources.count(); ++i) { | 673 for (int i = 0; i < fNonpurgeableResources.count(); ++i) { |
589 SkASSERT(!fNonpurgeableResources[i]->isPurgeable()); | 674 SkASSERT(!fNonpurgeableResources[i]->isPurgeable() || |
| 675 fNewlyPurgeableResourceForValidation == fNonpurgeableResources[
i]); |
590 SkASSERT(*fNonpurgeableResources[i]->cacheAccess().accessCacheIndex() ==
i); | 676 SkASSERT(*fNonpurgeableResources[i]->cacheAccess().accessCacheIndex() ==
i); |
591 SkASSERT(!fNonpurgeableResources[i]->wasDestroyed()); | 677 SkASSERT(!fNonpurgeableResources[i]->wasDestroyed()); |
592 stats.update(fNonpurgeableResources[i]); | 678 stats.update(fNonpurgeableResources[i]); |
593 } | 679 } |
594 for (int i = 0; i < fPurgeableQueue.count(); ++i) { | 680 for (int i = 0; i < fPurgeableQueue.count(); ++i) { |
595 SkASSERT(fPurgeableQueue.at(i)->isPurgeable()); | 681 SkASSERT(fPurgeableQueue.at(i)->isPurgeable()); |
596 SkASSERT(*fPurgeableQueue.at(i)->cacheAccess().accessCacheIndex() == i); | 682 SkASSERT(*fPurgeableQueue.at(i)->cacheAccess().accessCacheIndex() == i); |
597 SkASSERT(!fPurgeableQueue.at(i)->wasDestroyed()); | 683 SkASSERT(!fPurgeableQueue.at(i)->wasDestroyed()); |
598 stats.update(fPurgeableQueue.at(i)); | 684 stats.update(fPurgeableQueue.at(i)); |
599 } | 685 } |
600 | 686 |
601 SkASSERT(fCount == this->getResourceCount()); | 687 SkASSERT(fCount == this->getResourceCount()); |
602 SkASSERT(fBudgetedCount <= fCount); | 688 SkASSERT(fBudgetedCount <= fCount); |
603 SkASSERT(fBudgetedBytes <= fBytes); | 689 SkASSERT(fBudgetedBytes <= fBytes); |
604 SkASSERT(stats.fBytes == fBytes); | 690 SkASSERT(stats.fBytes == fBytes); |
605 SkASSERT(stats.fBudgetedBytes == fBudgetedBytes); | 691 SkASSERT(stats.fBudgetedBytes == fBudgetedBytes); |
606 SkASSERT(stats.fBudgetedCount == fBudgetedCount); | 692 SkASSERT(stats.fBudgetedCount == fBudgetedCount); |
607 #if GR_CACHE_STATS | 693 #if GR_CACHE_STATS |
608 SkASSERT(fBudgetedHighWaterCount <= fHighWaterCount); | 694 SkASSERT(fBudgetedHighWaterCount <= fHighWaterCount); |
609 SkASSERT(fBudgetedHighWaterBytes <= fHighWaterBytes); | 695 SkASSERT(fBudgetedHighWaterBytes <= fHighWaterBytes); |
610 SkASSERT(fBytes <= fHighWaterBytes); | 696 SkASSERT(fBytes <= fHighWaterBytes); |
611 SkASSERT(fCount <= fHighWaterCount); | 697 SkASSERT(fCount <= fHighWaterCount); |
612 SkASSERT(fBudgetedBytes <= fBudgetedHighWaterBytes); | 698 SkASSERT(fBudgetedBytes <= fBudgetedHighWaterBytes); |
613 SkASSERT(fBudgetedCount <= fBudgetedHighWaterCount); | 699 SkASSERT(fBudgetedCount <= fBudgetedHighWaterCount); |
614 #endif | 700 #endif |
615 SkASSERT(stats.fContent == fUniqueHash.count()); | 701 SkASSERT(stats.fContent == fUniqueHash.count()); |
616 SkASSERT(stats.fScratch + stats.fCouldBeScratch == fScratchMap.count()); | 702 SkASSERT(stats.fScratch + stats.fCouldBeScratch == fScratchMap.count()); |
617 | 703 |
618 // This assertion is not currently valid because we can be in recursive noti
fyIsPurgeable() | 704 // This assertion is not currently valid because we can be in recursive noti
fyCntReachedZero() |
619 // calls. This will be fixed when subresource registration is explicit. | 705 // calls. This will be fixed when subresource registration is explicit. |
620 // bool overBudget = budgetedBytes > fMaxBytes || budgetedCount > fMaxCount; | 706 // bool overBudget = budgetedBytes > fMaxBytes || budgetedCount > fMaxCount; |
621 // SkASSERT(!overBudget || locked == count || fPurging); | 707 // SkASSERT(!overBudget || locked == count || fPurging); |
622 } | 708 } |
623 | 709 |
624 bool GrResourceCache::isInCache(const GrGpuResource* resource) const { | 710 bool GrResourceCache::isInCache(const GrGpuResource* resource) const { |
625 int index = *resource->cacheAccess().accessCacheIndex(); | 711 int index = *resource->cacheAccess().accessCacheIndex(); |
626 if (index < 0) { | 712 if (index < 0) { |
627 return false; | 713 return false; |
628 } | 714 } |
629 if (index < fPurgeableQueue.count() && fPurgeableQueue.at(index) == resource
) { | 715 if (index < fPurgeableQueue.count() && fPurgeableQueue.at(index) == resource
) { |
630 return true; | 716 return true; |
631 } | 717 } |
632 if (index < fNonpurgeableResources.count() && fNonpurgeableResources[index]
== resource) { | 718 if (index < fNonpurgeableResources.count() && fNonpurgeableResources[index]
== resource) { |
633 return true; | 719 return true; |
634 } | 720 } |
635 SkDEBUGFAIL("Resource index should be -1 or the resource should be in the ca
che."); | 721 SkDEBUGFAIL("Resource index should be -1 or the resource should be in the ca
che."); |
636 return false; | 722 return false; |
637 } | 723 } |
638 | 724 |
639 #endif | 725 #endif |
OLD | NEW |