| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 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 #include "SkChecksum.h" | 8 #include "SkChecksum.h" |
| 9 #include "SkScaledImageCache.h" | 9 #include "SkScaledImageCache.h" |
| 10 #include "SkMipMap.h" | 10 #include "SkMipMap.h" |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 #endif | 133 #endif |
| 134 | 134 |
| 135 void SkScaledImageCache::init() { | 135 void SkScaledImageCache::init() { |
| 136 fHead = NULL; | 136 fHead = NULL; |
| 137 fTail = NULL; | 137 fTail = NULL; |
| 138 #ifdef USE_HASH | 138 #ifdef USE_HASH |
| 139 fHash = new Hash; | 139 fHash = new Hash; |
| 140 #else | 140 #else |
| 141 fHash = NULL; | 141 fHash = NULL; |
| 142 #endif | 142 #endif |
| 143 fBytesUsed = 0; | 143 fTotalBytesUsed = 0; |
| 144 fCount = 0; | 144 fCount = 0; |
| 145 fSingleAllocationByteLimit = 0; |
| 145 fAllocator = NULL; | 146 fAllocator = NULL; |
| 146 | 147 |
| 147 // One of these should be explicit set by the caller after we return. | 148 // One of these should be explicit set by the caller after we return. |
| 148 fByteLimit = 0; | 149 fTotalByteLimit = 0; |
| 149 fDiscardableFactory = NULL; | 150 fDiscardableFactory = NULL; |
| 150 } | 151 } |
| 151 | 152 |
| 152 #include "SkDiscardableMemory.h" | 153 #include "SkDiscardableMemory.h" |
| 153 | 154 |
| 154 class SkOneShotDiscardablePixelRef : public SkPixelRef { | 155 class SkOneShotDiscardablePixelRef : public SkPixelRef { |
| 155 public: | 156 public: |
| 156 SK_DECLARE_INST_COUNT(SkOneShotDiscardablePixelRef) | 157 SK_DECLARE_INST_COUNT(SkOneShotDiscardablePixelRef) |
| 157 // Ownership of the discardablememory is transfered to the pixelref | 158 // Ownership of the discardablememory is transfered to the pixelref |
| 158 SkOneShotDiscardablePixelRef(const SkImageInfo&, SkDiscardableMemory*, size_
t rowBytes); | 159 SkOneShotDiscardablePixelRef(const SkImageInfo&, SkDiscardableMemory*, size_
t rowBytes); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 | 264 |
| 264 SkScaledImageCache::SkScaledImageCache(DiscardableFactory factory) { | 265 SkScaledImageCache::SkScaledImageCache(DiscardableFactory factory) { |
| 265 this->init(); | 266 this->init(); |
| 266 fDiscardableFactory = factory; | 267 fDiscardableFactory = factory; |
| 267 | 268 |
| 268 fAllocator = SkNEW_ARGS(SkScaledImageCacheDiscardableAllocator, (factory)); | 269 fAllocator = SkNEW_ARGS(SkScaledImageCacheDiscardableAllocator, (factory)); |
| 269 } | 270 } |
| 270 | 271 |
| 271 SkScaledImageCache::SkScaledImageCache(size_t byteLimit) { | 272 SkScaledImageCache::SkScaledImageCache(size_t byteLimit) { |
| 272 this->init(); | 273 this->init(); |
| 273 fByteLimit = byteLimit; | 274 fTotalByteLimit = byteLimit; |
| 274 } | 275 } |
| 275 | 276 |
| 276 SkScaledImageCache::~SkScaledImageCache() { | 277 SkScaledImageCache::~SkScaledImageCache() { |
| 277 SkSafeUnref(fAllocator); | 278 SkSafeUnref(fAllocator); |
| 278 | 279 |
| 279 Rec* rec = fHead; | 280 Rec* rec = fHead; |
| 280 while (rec) { | 281 while (rec) { |
| 281 Rec* next = rec->fNext; | 282 Rec* next = rec->fNext; |
| 282 SkDELETE(rec); | 283 SkDELETE(rec); |
| 283 rec = next; | 284 rec = next; |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 | 469 |
| 469 void SkScaledImageCache::purgeAsNeeded() { | 470 void SkScaledImageCache::purgeAsNeeded() { |
| 470 size_t byteLimit; | 471 size_t byteLimit; |
| 471 int countLimit; | 472 int countLimit; |
| 472 | 473 |
| 473 if (fDiscardableFactory) { | 474 if (fDiscardableFactory) { |
| 474 countLimit = SK_DISCARDABLEMEMORY_SCALEDIMAGECACHE_COUNT_LIMIT; | 475 countLimit = SK_DISCARDABLEMEMORY_SCALEDIMAGECACHE_COUNT_LIMIT; |
| 475 byteLimit = SK_MaxU32; // no limit based on bytes | 476 byteLimit = SK_MaxU32; // no limit based on bytes |
| 476 } else { | 477 } else { |
| 477 countLimit = SK_MaxS32; // no limit based on count | 478 countLimit = SK_MaxS32; // no limit based on count |
| 478 byteLimit = fByteLimit; | 479 byteLimit = fTotalByteLimit; |
| 479 } | 480 } |
| 480 | 481 |
| 481 size_t bytesUsed = fBytesUsed; | 482 size_t bytesUsed = fTotalBytesUsed; |
| 482 int countUsed = fCount; | 483 int countUsed = fCount; |
| 483 | 484 |
| 484 Rec* rec = fTail; | 485 Rec* rec = fTail; |
| 485 while (rec) { | 486 while (rec) { |
| 486 if (bytesUsed < byteLimit && countUsed < countLimit) { | 487 if (bytesUsed < byteLimit && countUsed < countLimit) { |
| 487 break; | 488 break; |
| 488 } | 489 } |
| 489 | 490 |
| 490 Rec* prev = rec->fPrev; | 491 Rec* prev = rec->fPrev; |
| 491 if (0 == rec->fLockCount) { | 492 if (0 == rec->fLockCount) { |
| 492 size_t used = rec->bytesUsed(); | 493 size_t used = rec->bytesUsed(); |
| 493 SkASSERT(used <= bytesUsed); | 494 SkASSERT(used <= bytesUsed); |
| 494 this->detach(rec); | 495 this->detach(rec); |
| 495 #ifdef USE_HASH | 496 #ifdef USE_HASH |
| 496 fHash->remove(rec->fKey); | 497 fHash->remove(rec->fKey); |
| 497 #endif | 498 #endif |
| 498 | 499 |
| 499 SkDELETE(rec); | 500 SkDELETE(rec); |
| 500 | 501 |
| 501 bytesUsed -= used; | 502 bytesUsed -= used; |
| 502 countUsed -= 1; | 503 countUsed -= 1; |
| 503 } | 504 } |
| 504 rec = prev; | 505 rec = prev; |
| 505 } | 506 } |
| 506 | 507 |
| 507 fBytesUsed = bytesUsed; | 508 fTotalBytesUsed = bytesUsed; |
| 508 fCount = countUsed; | 509 fCount = countUsed; |
| 509 } | 510 } |
| 510 | 511 |
| 511 size_t SkScaledImageCache::setByteLimit(size_t newLimit) { | 512 size_t SkScaledImageCache::setTotalByteLimit(size_t newLimit) { |
| 512 size_t prevLimit = fByteLimit; | 513 size_t prevLimit = fTotalByteLimit; |
| 513 fByteLimit = newLimit; | 514 fTotalByteLimit = newLimit; |
| 514 if (newLimit < prevLimit) { | 515 if (newLimit < prevLimit) { |
| 515 this->purgeAsNeeded(); | 516 this->purgeAsNeeded(); |
| 516 } | 517 } |
| 517 return prevLimit; | 518 return prevLimit; |
| 518 } | 519 } |
| 519 | 520 |
| 520 /////////////////////////////////////////////////////////////////////////////// | 521 /////////////////////////////////////////////////////////////////////////////// |
| 521 | 522 |
| 522 void SkScaledImageCache::detach(Rec* rec) { | 523 void SkScaledImageCache::detach(Rec* rec) { |
| 523 Rec* prev = rec->fPrev; | 524 Rec* prev = rec->fPrev; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 | 564 |
| 564 rec->fPrev = NULL; | 565 rec->fPrev = NULL; |
| 565 rec->fNext = fHead; | 566 rec->fNext = fHead; |
| 566 if (fHead) { | 567 if (fHead) { |
| 567 fHead->fPrev = rec; | 568 fHead->fPrev = rec; |
| 568 } | 569 } |
| 569 fHead = rec; | 570 fHead = rec; |
| 570 if (!fTail) { | 571 if (!fTail) { |
| 571 fTail = rec; | 572 fTail = rec; |
| 572 } | 573 } |
| 573 fBytesUsed += rec->bytesUsed(); | 574 fTotalBytesUsed += rec->bytesUsed(); |
| 574 fCount += 1; | 575 fCount += 1; |
| 575 | 576 |
| 576 this->validate(); | 577 this->validate(); |
| 577 } | 578 } |
| 578 | 579 |
| 579 /////////////////////////////////////////////////////////////////////////////// | 580 /////////////////////////////////////////////////////////////////////////////// |
| 580 | 581 |
| 581 #ifdef SK_DEBUG | 582 #ifdef SK_DEBUG |
| 582 void SkScaledImageCache::validate() const { | 583 void SkScaledImageCache::validate() const { |
| 583 if (NULL == fHead) { | 584 if (NULL == fHead) { |
| 584 SkASSERT(NULL == fTail); | 585 SkASSERT(NULL == fTail); |
| 585 SkASSERT(0 == fBytesUsed); | 586 SkASSERT(0 == fTotalBytesUsed); |
| 586 return; | 587 return; |
| 587 } | 588 } |
| 588 | 589 |
| 589 if (fHead == fTail) { | 590 if (fHead == fTail) { |
| 590 SkASSERT(NULL == fHead->fPrev); | 591 SkASSERT(NULL == fHead->fPrev); |
| 591 SkASSERT(NULL == fHead->fNext); | 592 SkASSERT(NULL == fHead->fNext); |
| 592 SkASSERT(fHead->bytesUsed() == fBytesUsed); | 593 SkASSERT(fHead->bytesUsed() == fTotalBytesUsed); |
| 593 return; | 594 return; |
| 594 } | 595 } |
| 595 | 596 |
| 596 SkASSERT(NULL == fHead->fPrev); | 597 SkASSERT(NULL == fHead->fPrev); |
| 597 SkASSERT(NULL != fHead->fNext); | 598 SkASSERT(NULL != fHead->fNext); |
| 598 SkASSERT(NULL == fTail->fNext); | 599 SkASSERT(NULL == fTail->fNext); |
| 599 SkASSERT(NULL != fTail->fPrev); | 600 SkASSERT(NULL != fTail->fPrev); |
| 600 | 601 |
| 601 size_t used = 0; | 602 size_t used = 0; |
| 602 int count = 0; | 603 int count = 0; |
| 603 const Rec* rec = fHead; | 604 const Rec* rec = fHead; |
| 604 while (rec) { | 605 while (rec) { |
| 605 count += 1; | 606 count += 1; |
| 606 used += rec->bytesUsed(); | 607 used += rec->bytesUsed(); |
| 607 SkASSERT(used <= fBytesUsed); | 608 SkASSERT(used <= fTotalBytesUsed); |
| 608 rec = rec->fNext; | 609 rec = rec->fNext; |
| 609 } | 610 } |
| 610 SkASSERT(fCount == count); | 611 SkASSERT(fCount == count); |
| 611 | 612 |
| 612 rec = fTail; | 613 rec = fTail; |
| 613 while (rec) { | 614 while (rec) { |
| 614 SkASSERT(count > 0); | 615 SkASSERT(count > 0); |
| 615 count -= 1; | 616 count -= 1; |
| 616 SkASSERT(used >= rec->bytesUsed()); | 617 SkASSERT(used >= rec->bytesUsed()); |
| 617 used -= rec->bytesUsed(); | 618 used -= rec->bytesUsed(); |
| 618 rec = rec->fPrev; | 619 rec = rec->fPrev; |
| 619 } | 620 } |
| 620 | 621 |
| 621 SkASSERT(0 == count); | 622 SkASSERT(0 == count); |
| 622 SkASSERT(0 == used); | 623 SkASSERT(0 == used); |
| 623 } | 624 } |
| 624 #endif | 625 #endif |
| 625 | 626 |
| 626 void SkScaledImageCache::dump() const { | 627 void SkScaledImageCache::dump() const { |
| 627 this->validate(); | 628 this->validate(); |
| 628 | 629 |
| 629 const Rec* rec = fHead; | 630 const Rec* rec = fHead; |
| 630 int locked = 0; | 631 int locked = 0; |
| 631 while (rec) { | 632 while (rec) { |
| 632 locked += rec->fLockCount > 0; | 633 locked += rec->fLockCount > 0; |
| 633 rec = rec->fNext; | 634 rec = rec->fNext; |
| 634 } | 635 } |
| 635 | 636 |
| 636 SkDebugf("SkScaledImageCache: count=%d bytes=%d locked=%d %s\n", | 637 SkDebugf("SkScaledImageCache: count=%d bytes=%d locked=%d %s\n", |
| 637 fCount, fBytesUsed, locked, | 638 fCount, fTotalBytesUsed, locked, |
| 638 fDiscardableFactory ? "discardable" : "malloc"); | 639 fDiscardableFactory ? "discardable" : "malloc"); |
| 639 } | 640 } |
| 640 | 641 |
| 642 size_t SkScaledImageCache::setSingleAllocationByteLimit(size_t newLimit) { |
| 643 size_t oldLimit = fSingleAllocationByteLimit; |
| 644 fSingleAllocationByteLimit = newLimit; |
| 645 return oldLimit; |
| 646 } |
| 647 |
| 648 size_t SkScaledImageCache::getSingleAllocationByteLimit() const { |
| 649 return fSingleAllocationByteLimit; |
| 650 } |
| 651 |
| 641 /////////////////////////////////////////////////////////////////////////////// | 652 /////////////////////////////////////////////////////////////////////////////// |
| 642 | 653 |
| 643 #include "SkThread.h" | 654 #include "SkThread.h" |
| 644 | 655 |
| 645 SK_DECLARE_STATIC_MUTEX(gMutex); | 656 SK_DECLARE_STATIC_MUTEX(gMutex); |
| 646 static SkScaledImageCache* gScaledImageCache = NULL; | 657 static SkScaledImageCache* gScaledImageCache = NULL; |
| 647 static void cleanup_gScaledImageCache() { | 658 static void cleanup_gScaledImageCache() { |
| 648 // We'll clean this up in our own tests, but disable for clients. | 659 // We'll clean this up in our own tests, but disable for clients. |
| 649 // Chrome seems to have funky multi-process things going on in unit tests th
at | 660 // Chrome seems to have funky multi-process things going on in unit tests th
at |
| 650 // makes this unsafe to delete when the main process atexit()s. | 661 // makes this unsafe to delete when the main process atexit()s. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 return get_cache()->addAndLockMip(orig, mip); | 728 return get_cache()->addAndLockMip(orig, mip); |
| 718 } | 729 } |
| 719 | 730 |
| 720 void SkScaledImageCache::Unlock(SkScaledImageCache::ID* id) { | 731 void SkScaledImageCache::Unlock(SkScaledImageCache::ID* id) { |
| 721 SkAutoMutexAcquire am(gMutex); | 732 SkAutoMutexAcquire am(gMutex); |
| 722 get_cache()->unlock(id); | 733 get_cache()->unlock(id); |
| 723 | 734 |
| 724 // get_cache()->dump(); | 735 // get_cache()->dump(); |
| 725 } | 736 } |
| 726 | 737 |
| 727 size_t SkScaledImageCache::GetBytesUsed() { | 738 size_t SkScaledImageCache::GetTotalBytesUsed() { |
| 728 SkAutoMutexAcquire am(gMutex); | 739 SkAutoMutexAcquire am(gMutex); |
| 729 return get_cache()->getBytesUsed(); | 740 return get_cache()->getTotalBytesUsed(); |
| 730 } | 741 } |
| 731 | 742 |
| 732 size_t SkScaledImageCache::GetByteLimit() { | 743 size_t SkScaledImageCache::GetTotalByteLimit() { |
| 733 SkAutoMutexAcquire am(gMutex); | 744 SkAutoMutexAcquire am(gMutex); |
| 734 return get_cache()->getByteLimit(); | 745 return get_cache()->getTotalByteLimit(); |
| 735 } | 746 } |
| 736 | 747 |
| 737 size_t SkScaledImageCache::SetByteLimit(size_t newLimit) { | 748 size_t SkScaledImageCache::SetTotalByteLimit(size_t newLimit) { |
| 738 SkAutoMutexAcquire am(gMutex); | 749 SkAutoMutexAcquire am(gMutex); |
| 739 return get_cache()->setByteLimit(newLimit); | 750 return get_cache()->setTotalByteLimit(newLimit); |
| 740 } | 751 } |
| 741 | 752 |
| 742 SkBitmap::Allocator* SkScaledImageCache::GetAllocator() { | 753 SkBitmap::Allocator* SkScaledImageCache::GetAllocator() { |
| 743 SkAutoMutexAcquire am(gMutex); | 754 SkAutoMutexAcquire am(gMutex); |
| 744 return get_cache()->allocator(); | 755 return get_cache()->allocator(); |
| 745 } | 756 } |
| 746 | 757 |
| 747 void SkScaledImageCache::Dump() { | 758 void SkScaledImageCache::Dump() { |
| 748 SkAutoMutexAcquire am(gMutex); | 759 SkAutoMutexAcquire am(gMutex); |
| 749 get_cache()->dump(); | 760 get_cache()->dump(); |
| 750 } | 761 } |
| 751 | 762 |
| 763 size_t SkScaledImageCache::SetSingleAllocationByteLimit(size_t size) { |
| 764 SkAutoMutexAcquire am(gMutex); |
| 765 return get_cache()->setSingleAllocationByteLimit(size); |
| 766 } |
| 767 |
| 768 size_t SkScaledImageCache::GetSingleAllocationByteLimit() { |
| 769 SkAutoMutexAcquire am(gMutex); |
| 770 return get_cache()->getSingleAllocationByteLimit(); |
| 771 } |
| 772 |
| 752 /////////////////////////////////////////////////////////////////////////////// | 773 /////////////////////////////////////////////////////////////////////////////// |
| 753 | 774 |
| 754 #include "SkGraphics.h" | 775 #include "SkGraphics.h" |
| 755 | 776 |
| 756 size_t SkGraphics::GetImageCacheBytesUsed() { | 777 size_t SkGraphics::GetImageCacheTotalBytesUsed() { |
| 757 return SkScaledImageCache::GetBytesUsed(); | 778 return SkScaledImageCache::GetTotalBytesUsed(); |
| 758 } | 779 } |
| 759 | 780 |
| 760 size_t SkGraphics::GetImageCacheByteLimit() { | 781 size_t SkGraphics::GetImageCacheTotalByteLimit() { |
| 761 return SkScaledImageCache::GetByteLimit(); | 782 return SkScaledImageCache::GetTotalByteLimit(); |
| 762 } | 783 } |
| 763 | 784 |
| 764 size_t SkGraphics::SetImageCacheByteLimit(size_t newLimit) { | 785 size_t SkGraphics::SetImageCacheTotalByteLimit(size_t newLimit) { |
| 765 return SkScaledImageCache::SetByteLimit(newLimit); | 786 return SkScaledImageCache::SetTotalByteLimit(newLimit); |
| 766 } | 787 } |
| 788 |
| 789 size_t SkGraphics::GetImageCacheSingleAllocationByteLimit() { |
| 790 return SkScaledImageCache::GetSingleAllocationByteLimit(); |
| 791 } |
| 792 |
| 793 size_t SkGraphics::SetImageCacheSingleAllocationByteLimit(size_t newLimit) { |
| 794 return SkScaledImageCache::SetSingleAllocationByteLimit(newLimit); |
| 795 } |
| 796 |
| OLD | NEW |