| Index: src/core/SkScaledImageCache.cpp
|
| diff --git a/src/core/SkScaledImageCache.cpp b/src/core/SkScaledImageCache.cpp
|
| index 11a0ee448f9c7cd590ff81c3409afded24163d8d..c925aee1c39731719f330d61f4982ea0cbc0de11 100644
|
| --- a/src/core/SkScaledImageCache.cpp
|
| +++ b/src/core/SkScaledImageCache.cpp
|
| @@ -7,6 +7,7 @@
|
|
|
| #include "SkScaledImageCache.h"
|
| #include "SkMipMap.h"
|
| +#include "SkOnce.h"
|
| #include "SkPixelRef.h"
|
| #include "SkRect.h"
|
|
|
| @@ -54,13 +55,25 @@ struct Key {
|
|
|
| fGenID = pr->getGenerationID();
|
| fBounds.set(x, y, x + bm.width(), y + bm.height());
|
| - fScaleX = scaleX;
|
| - fScaleY = scaleY;
|
| + fScaleX = SkScalarToFloat(scaleX);
|
| + fScaleY = SkScalarToFloat(scaleY);
|
|
|
| fHash = compute_hash(&fGenID, 7);
|
| return true;
|
| }
|
|
|
| + void init(int32_t width,
|
| + int32_t height,
|
| + uint32_t genID,
|
| + SkScalar scaleX,
|
| + SkScalar scaleY) {
|
| + fBounds.set(0, 0, width, height);
|
| + fGenID = genID;
|
| + fScaleX = SkScalarToFloat(scaleX);
|
| + fScaleY = SkScalarToFloat(scaleY);
|
| + fHash = compute_hash(&fGenID, 7);
|
| + }
|
| +
|
| bool operator<(const Key& other) const {
|
| const uint32_t* a = &fGenID;
|
| const uint32_t* b = &other.fGenID;
|
| @@ -174,6 +187,15 @@ SkScaledImageCache::~SkScaledImageCache() {
|
| delete fHash;
|
| }
|
|
|
| +static inline SkScaledImageCache::Rec* find_rec_in_list(
|
| + SkScaledImageCache::Rec* head, const Key & key) {
|
| + SkScaledImageCache::Rec* rec = head;
|
| + while ((rec != NULL) && !(rec->fKey == key)) {
|
| + rec = rec->fNext;
|
| + }
|
| + return rec;
|
| +}
|
| +
|
| SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(const SkBitmap& orig,
|
| SkScalar scaleX,
|
| SkScalar scaleY) {
|
| @@ -185,15 +207,8 @@ SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(const SkBitmap& orig,
|
| #ifdef USE_HASH
|
| Rec* rec = fHash->find(key);
|
| #else
|
| - Rec* rec = fHead;
|
| - while (rec != NULL) {
|
| - if (rec->fKey == key) {
|
| - break;
|
| - }
|
| - rec = rec->fNext;
|
| - }
|
| + Rec* rec = find_rec_in_list(fHead, key);
|
| #endif
|
| -
|
| if (rec) {
|
| this->moveToHead(rec); // for our LRU
|
| rec->fLockCount += 1;
|
| @@ -201,6 +216,29 @@ SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(const SkBitmap& orig,
|
| return rec;
|
| }
|
|
|
| +
|
| +SkScaledImageCache::ID* SkScaledImageCache::findAndLock(
|
| + uint32_t pixelGenerationID,
|
| + int32_t width,
|
| + int32_t height,
|
| + SkBitmap* scaled) {
|
| + Key key;
|
| + key.init(width, height, pixelGenerationID, SK_Scalar1, SK_Scalar1);
|
| +#ifdef USE_HASH
|
| + Rec* rec = fHash->find(key);
|
| +#else
|
| + Rec* rec = find_rec_in_list(fHead, key);
|
| +#endif
|
| + if (rec) {
|
| + this->moveToHead(rec); // for our LRU
|
| + rec->fLockCount += 1;
|
| + SkASSERT(NULL == rec->fMip);
|
| + SkASSERT(rec->fBitmap.pixelRef());
|
| + *scaled = rec->fBitmap;
|
| + }
|
| + return reinterpret_cast<ID*>(rec);
|
| +}
|
| +
|
| SkScaledImageCache::ID* SkScaledImageCache::findAndLock(const SkBitmap& orig,
|
| SkScalar scaleX,
|
| SkScalar scaleY,
|
| @@ -230,6 +268,26 @@ SkScaledImageCache::ID* SkScaledImageCache::findAndLockMip(const SkBitmap& orig,
|
| return (ID*)rec;
|
| }
|
|
|
| +SkScaledImageCache::ID* SkScaledImageCache::addAndLock(
|
| + uint32_t pixelGenerationID,
|
| + int32_t width,
|
| + int32_t height,
|
| + const SkBitmap& scaled) {
|
| + Key key;
|
| + key.init(width, height, pixelGenerationID, SK_Scalar1, SK_Scalar1);
|
| + Rec* rec = SkNEW_ARGS(Rec, (key, scaled));
|
| + this->addToHead(rec);
|
| + SkASSERT(1 == rec->fLockCount);
|
| +
|
| +#ifdef USE_HASH
|
| + fHash->add(rec);
|
| +#endif
|
| +
|
| + // We may (now) be overbudget, so see if we need to purge something.
|
| + this->purgeAsNeeded();
|
| + return reinterpret_cast<ID*>(rec);
|
| +}
|
| +
|
| SkScaledImageCache::ID* SkScaledImageCache::addAndLock(const SkBitmap& orig,
|
| SkScalar scaleX,
|
| SkScalar scaleY,
|
| @@ -451,14 +509,37 @@ void SkScaledImageCache::validate() const {
|
|
|
| SK_DECLARE_STATIC_MUTEX(gMutex);
|
|
|
| +DEF_SK_ONCE(create_cache, SkScaledImageCache** cache) {
|
| + *cache = SkNEW_ARGS(SkScaledImageCache, (SK_DEFAULT_IMAGE_CACHE_LIMIT));
|
| +}
|
| +
|
| static SkScaledImageCache* get_cache() {
|
| - static SkScaledImageCache* gCache;
|
| - if (!gCache) {
|
| - gCache = SkNEW_ARGS(SkScaledImageCache, (SK_DEFAULT_IMAGE_CACHE_LIMIT));
|
| - }
|
| + static SkScaledImageCache* gCache = NULL;
|
| + SK_ONCE(create_cache, &gCache);
|
| + SkASSERT(NULL != gCache);
|
| return gCache;
|
| }
|
|
|
| +
|
| +SkScaledImageCache::ID* SkScaledImageCache::FindAndLock(
|
| + uint32_t pixelGenerationID,
|
| + int32_t width,
|
| + int32_t height,
|
| + SkBitmap* scaled) {
|
| + SkAutoMutexAcquire am(gMutex);
|
| + return get_cache()->findAndLock(pixelGenerationID, width, height, scaled);
|
| +}
|
| +
|
| +SkScaledImageCache::ID* SkScaledImageCache::AddAndLock(
|
| + uint32_t pixelGenerationID,
|
| + int32_t width,
|
| + int32_t height,
|
| + const SkBitmap& scaled) {
|
| + SkAutoMutexAcquire am(gMutex);
|
| + return get_cache()->addAndLock(pixelGenerationID, width, height, scaled);
|
| +}
|
| +
|
| +
|
| SkScaledImageCache::ID* SkScaledImageCache::FindAndLock(const SkBitmap& orig,
|
| SkScalar scaleX,
|
| SkScalar scaleY,
|
|
|