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