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