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