OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2010 Google Inc. | 3 * Copyright 2010 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 | 10 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 fCache.remove(entry->fKey, entry); | 110 fCache.remove(entry->fKey, entry); |
111 | 111 |
112 // remove from our llist | 112 // remove from our llist |
113 this->internalDetach(entry); | 113 this->internalDetach(entry); |
114 | 114 |
115 delete entry; | 115 delete entry; |
116 } | 116 } |
117 } | 117 } |
118 | 118 |
119 void GrResourceCache::getLimits(int* maxResources, size_t* maxResourceBytes) con
st{ | 119 void GrResourceCache::getLimits(int* maxResources, size_t* maxResourceBytes) con
st{ |
120 if (NULL != maxResources) { | 120 if (maxResources) { |
121 *maxResources = fMaxCount; | 121 *maxResources = fMaxCount; |
122 } | 122 } |
123 if (NULL != maxResourceBytes) { | 123 if (maxResourceBytes) { |
124 *maxResourceBytes = fMaxBytes; | 124 *maxResourceBytes = fMaxBytes; |
125 } | 125 } |
126 } | 126 } |
127 | 127 |
128 void GrResourceCache::setLimits(int maxResources, size_t maxResourceBytes) { | 128 void GrResourceCache::setLimits(int maxResources, size_t maxResourceBytes) { |
129 bool smaller = (maxResources < fMaxCount) || (maxResourceBytes < fMaxBytes); | 129 bool smaller = (maxResources < fMaxCount) || (maxResourceBytes < fMaxBytes); |
130 | 130 |
131 fMaxCount = maxResources; | 131 fMaxCount = maxResources; |
132 fMaxBytes = maxResourceBytes; | 132 fMaxBytes = maxResourceBytes; |
133 | 133 |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 return; | 336 return; |
337 } | 337 } |
338 | 338 |
339 fPurging = true; | 339 fPurging = true; |
340 | 340 |
341 this->purgeInvalidated(); | 341 this->purgeInvalidated(); |
342 | 342 |
343 this->internalPurge(extraCount, extraBytes); | 343 this->internalPurge(extraCount, extraBytes); |
344 if (((fEntryCount+extraCount) > fMaxCount || | 344 if (((fEntryCount+extraCount) > fMaxCount || |
345 (fEntryBytes+extraBytes) > fMaxBytes) && | 345 (fEntryBytes+extraBytes) > fMaxBytes) && |
346 NULL != fOverbudgetCB) { | 346 fOverbudgetCB) { |
347 // Despite the purge we're still over budget. See if Ganesh can | 347 // Despite the purge we're still over budget. See if Ganesh can |
348 // release some resources and purge again. | 348 // release some resources and purge again. |
349 if ((*fOverbudgetCB)(fOverbudgetData)) { | 349 if ((*fOverbudgetCB)(fOverbudgetData)) { |
350 this->internalPurge(extraCount, extraBytes); | 350 this->internalPurge(extraCount, extraBytes); |
351 } | 351 } |
352 } | 352 } |
353 | 353 |
354 fPurging = false; | 354 fPurging = false; |
355 } | 355 } |
356 | 356 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 EntryList::Iter iter; | 395 EntryList::Iter iter; |
396 | 396 |
397 changed = false; | 397 changed = false; |
398 | 398 |
399 // Note: the following code relies on the fact that the | 399 // Note: the following code relies on the fact that the |
400 // doubly linked list doesn't invalidate its data/pointers | 400 // doubly linked list doesn't invalidate its data/pointers |
401 // outside of the specific area where a deletion occurs (e.g., | 401 // outside of the specific area where a deletion occurs (e.g., |
402 // in internalDetach) | 402 // in internalDetach) |
403 GrResourceCacheEntry* entry = iter.init(fList, EntryList::Iter::kTail_It
erStart); | 403 GrResourceCacheEntry* entry = iter.init(fList, EntryList::Iter::kTail_It
erStart); |
404 | 404 |
405 while (NULL != entry) { | 405 while (entry) { |
406 GrAutoResourceCacheValidate atcv(this); | 406 GrAutoResourceCacheValidate atcv(this); |
407 | 407 |
408 if ((fEntryCount+extraCount) <= fMaxCount && | 408 if ((fEntryCount+extraCount) <= fMaxCount && |
409 (fEntryBytes+extraBytes) <= fMaxBytes) { | 409 (fEntryBytes+extraBytes) <= fMaxBytes) { |
410 withinBudget = true; | 410 withinBudget = true; |
411 break; | 411 break; |
412 } | 412 } |
413 | 413 |
414 GrResourceCacheEntry* prev = iter.prev(); | 414 GrResourceCacheEntry* prev = iter.prev(); |
415 if (entry->fResource->unique()) { | 415 if (entry->fResource->unique()) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 | 455 |
456 #ifdef SK_DEBUG | 456 #ifdef SK_DEBUG |
457 size_t GrResourceCache::countBytes(const EntryList& list) { | 457 size_t GrResourceCache::countBytes(const EntryList& list) { |
458 size_t bytes = 0; | 458 size_t bytes = 0; |
459 | 459 |
460 EntryList::Iter iter; | 460 EntryList::Iter iter; |
461 | 461 |
462 const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(list), | 462 const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(list), |
463 EntryList::Iter::kTail_IterSta
rt); | 463 EntryList::Iter::kTail_IterSta
rt); |
464 | 464 |
465 for ( ; NULL != entry; entry = iter.prev()) { | 465 for ( ; entry; entry = iter.prev()) { |
466 bytes += entry->resource()->gpuMemorySize(); | 466 bytes += entry->resource()->gpuMemorySize(); |
467 } | 467 } |
468 return bytes; | 468 return bytes; |
469 } | 469 } |
470 | 470 |
471 static bool both_zero_or_nonzero(int count, size_t bytes) { | 471 static bool both_zero_or_nonzero(int count, size_t bytes) { |
472 return (count == 0 && bytes == 0) || (count > 0 && bytes > 0); | 472 return (count == 0 && bytes == 0) || (count > 0 && bytes > 0); |
473 } | 473 } |
474 | 474 |
475 void GrResourceCache::validate() const { | 475 void GrResourceCache::validate() const { |
476 fList.validate(); | 476 fList.validate(); |
477 fExclusiveList.validate(); | 477 fExclusiveList.validate(); |
478 SkASSERT(both_zero_or_nonzero(fEntryCount, fEntryBytes)); | 478 SkASSERT(both_zero_or_nonzero(fEntryCount, fEntryBytes)); |
479 SkASSERT(both_zero_or_nonzero(fClientDetachedCount, fClientDetachedBytes)); | 479 SkASSERT(both_zero_or_nonzero(fClientDetachedCount, fClientDetachedBytes)); |
480 SkASSERT(fClientDetachedBytes <= fEntryBytes); | 480 SkASSERT(fClientDetachedBytes <= fEntryBytes); |
481 SkASSERT(fClientDetachedCount <= fEntryCount); | 481 SkASSERT(fClientDetachedCount <= fEntryCount); |
482 SkASSERT((fEntryCount - fClientDetachedCount) == fCache.count()); | 482 SkASSERT((fEntryCount - fClientDetachedCount) == fCache.count()); |
483 | 483 |
484 EntryList::Iter iter; | 484 EntryList::Iter iter; |
485 | 485 |
486 // check that the exclusively held entries are okay | 486 // check that the exclusively held entries are okay |
487 const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(fExclus
iveList), | 487 const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(fExclus
iveList), |
488 EntryList::Iter::kHead_IterSta
rt); | 488 EntryList::Iter::kHead_IterSta
rt); |
489 | 489 |
490 for ( ; NULL != entry; entry = iter.next()) { | 490 for ( ; entry; entry = iter.next()) { |
491 entry->validate(); | 491 entry->validate(); |
492 } | 492 } |
493 | 493 |
494 // check that the shareable entries are okay | 494 // check that the shareable entries are okay |
495 entry = iter.init(const_cast<EntryList&>(fList), EntryList::Iter::kHead_Iter
Start); | 495 entry = iter.init(const_cast<EntryList&>(fList), EntryList::Iter::kHead_Iter
Start); |
496 | 496 |
497 int count = 0; | 497 int count = 0; |
498 for ( ; NULL != entry; entry = iter.next()) { | 498 for ( ; entry; entry = iter.next()) { |
499 entry->validate(); | 499 entry->validate(); |
500 SkASSERT(fCache.find(entry->key())); | 500 SkASSERT(fCache.find(entry->key())); |
501 count += 1; | 501 count += 1; |
502 } | 502 } |
503 SkASSERT(count == fEntryCount - fClientDetachedCount); | 503 SkASSERT(count == fEntryCount - fClientDetachedCount); |
504 | 504 |
505 size_t bytes = countBytes(fList); | 505 size_t bytes = countBytes(fList); |
506 SkASSERT(bytes == fEntryBytes - fClientDetachedBytes); | 506 SkASSERT(bytes == fEntryBytes - fClientDetachedBytes); |
507 | 507 |
508 bytes = countBytes(fExclusiveList); | 508 bytes = countBytes(fExclusiveList); |
509 SkASSERT(bytes == fClientDetachedBytes); | 509 SkASSERT(bytes == fClientDetachedBytes); |
510 | 510 |
511 SkASSERT(fList.countEntries() == fEntryCount - fClientDetachedCount); | 511 SkASSERT(fList.countEntries() == fEntryCount - fClientDetachedCount); |
512 | 512 |
513 SkASSERT(fExclusiveList.countEntries() == fClientDetachedCount); | 513 SkASSERT(fExclusiveList.countEntries() == fClientDetachedCount); |
514 } | 514 } |
515 #endif // SK_DEBUG | 515 #endif // SK_DEBUG |
516 | 516 |
517 #if GR_CACHE_STATS | 517 #if GR_CACHE_STATS |
518 | 518 |
519 void GrResourceCache::printStats() { | 519 void GrResourceCache::printStats() { |
520 int locked = 0; | 520 int locked = 0; |
521 | 521 |
522 EntryList::Iter iter; | 522 EntryList::Iter iter; |
523 | 523 |
524 GrResourceCacheEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterSt
art); | 524 GrResourceCacheEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterSt
art); |
525 | 525 |
526 for ( ; NULL != entry; entry = iter.prev()) { | 526 for ( ; entry; entry = iter.prev()) { |
527 if (entry->fResource->getRefCnt() > 1) { | 527 if (entry->fResource->getRefCnt() > 1) { |
528 ++locked; | 528 ++locked; |
529 } | 529 } |
530 } | 530 } |
531 | 531 |
532 SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes); | 532 SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes); |
533 SkDebugf("\t\tEntry Count: current %d (%d locked) high %d\n", | 533 SkDebugf("\t\tEntry Count: current %d (%d locked) high %d\n", |
534 fEntryCount, locked, fHighWaterEntryCount); | 534 fEntryCount, locked, fHighWaterEntryCount); |
535 SkDebugf("\t\tEntry Bytes: current %d high %d\n", | 535 SkDebugf("\t\tEntry Bytes: current %d high %d\n", |
536 fEntryBytes, fHighWaterEntryBytes); | 536 fEntryBytes, fHighWaterEntryBytes); |
537 SkDebugf("\t\tDetached Entry Count: current %d high %d\n", | 537 SkDebugf("\t\tDetached Entry Count: current %d high %d\n", |
538 fClientDetachedCount, fHighWaterClientDetachedCount); | 538 fClientDetachedCount, fHighWaterClientDetachedCount); |
539 SkDebugf("\t\tDetached Bytes: current %d high %d\n", | 539 SkDebugf("\t\tDetached Bytes: current %d high %d\n", |
540 fClientDetachedBytes, fHighWaterClientDetachedBytes); | 540 fClientDetachedBytes, fHighWaterClientDetachedBytes); |
541 } | 541 } |
542 | 542 |
543 #endif | 543 #endif |
544 | 544 |
545 /////////////////////////////////////////////////////////////////////////////// | 545 /////////////////////////////////////////////////////////////////////////////// |
OLD | NEW |