expose generalized imagecache key
BUG=skia:
R=mtklein@google.com, halcanary@google.com, qiankun.miao@intel.com
Author: reed@google.com
Review URL: https://codereview.chromium.org/483493003
diff --git a/src/core/SkBitmapCache.cpp b/src/core/SkBitmapCache.cpp
new file mode 100644
index 0000000..de52b63
--- /dev/null
+++ b/src/core/SkBitmapCache.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkBitmapCache.h"
+#include "SkRect.h"
+
+/**
+ This function finds the bounds of the bitmap *within its pixelRef*.
+ If the bitmap lacks a pixelRef, it will return an empty rect, since
+ that doesn't make sense. This may be a useful enough function that
+ it should be somewhere else (in SkBitmap?).
+ */
+static SkIRect get_bounds_from_bitmap(const SkBitmap& bm) {
+ if (!(bm.pixelRef())) {
+ return SkIRect::MakeEmpty();
+ }
+ SkIPoint origin = bm.pixelRefOrigin();
+ return SkIRect::MakeXYWH(origin.fX, origin.fY, bm.width(), bm.height());
+}
+
+struct BitmapKey : public SkScaledImageCache::Key {
+public:
+ BitmapKey(uint32_t genID, SkScalar scaleX, SkScalar scaleY, const SkIRect& bounds)
+ : fGenID(genID)
+ , fScaleX(scaleX)
+ , fScaleY(scaleY)
+ , fBounds(bounds)
+ {
+ this->init(sizeof(fGenID) + sizeof(fScaleX) + sizeof(fScaleY) + sizeof(fBounds));
+ }
+
+ uint32_t fGenID;
+ SkScalar fScaleX;
+ SkScalar fScaleY;
+ SkIRect fBounds;
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+SkScaledImageCache::ID* SkBitmapCache::FindAndLock(const SkBitmap& src,
+ SkScalar invScaleX, SkScalar invScaleY,
+ SkBitmap* result) {
+ if (0 == invScaleX || 0 == invScaleY) {
+ // degenerate, and the key we use for mipmaps
+ return NULL;
+ }
+ BitmapKey key(src.getGenerationID(), invScaleX, invScaleY, get_bounds_from_bitmap(src));
+ return SkScaledImageCache::FindAndLock(key, result);
+}
+
+SkScaledImageCache::ID* SkBitmapCache::AddAndLock(const SkBitmap& src,
+ SkScalar invScaleX, SkScalar invScaleY,
+ const SkBitmap& result) {
+ if (0 == invScaleX || 0 == invScaleY) {
+ // degenerate, and the key we use for mipmaps
+ return NULL;
+ }
+ BitmapKey key(src.getGenerationID(), invScaleX, invScaleY, get_bounds_from_bitmap(src));
+ return SkScaledImageCache::AddAndLock(key, result);
+}
+
+////
+
+SkScaledImageCache::ID* SkBitmapCache::FindAndLock(uint32_t genID, int width, int height,
+ SkBitmap* result) {
+ BitmapKey key(genID, SK_Scalar1, SK_Scalar1, SkIRect::MakeWH(width, height));
+ return SkScaledImageCache::FindAndLock(key, result);
+}
+
+SkScaledImageCache::ID* SkBitmapCache::AddAndLock(uint32_t genID, int width, int height,
+ const SkBitmap& result) {
+ BitmapKey key(genID, SK_Scalar1, SK_Scalar1, SkIRect::MakeWH(width, height));
+ return SkScaledImageCache::AddAndLock(key, result);
+}
+
+////
+
+SkScaledImageCache::ID* SkMipMapCache::FindAndLock(const SkBitmap& src, const SkMipMap** result) {
+ BitmapKey key(src.getGenerationID(), SK_Scalar1, SK_Scalar1, get_bounds_from_bitmap(src));
+ return SkScaledImageCache::FindAndLock(key, result);
+}
+
+SkScaledImageCache::ID* SkMipMapCache::AddAndLock(const SkBitmap& src, const SkMipMap* result) {
+ BitmapKey key(src.getGenerationID(), SK_Scalar1, SK_Scalar1, get_bounds_from_bitmap(src));
+ return SkScaledImageCache::AddAndLock(key, result);
+}
+
diff --git a/src/core/SkBitmapCache.h b/src/core/SkBitmapCache.h
new file mode 100644
index 0000000..ebade0e
--- /dev/null
+++ b/src/core/SkBitmapCache.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkBitmapCache_DEFINED
+#define SkBitmapCache_DEFINED
+
+#include "SkScaledImageCache.h"
+
+class SkBitmapCache {
+public:
+ typedef SkScaledImageCache::ID ID;
+
+ static void Unlock(ID* id) {
+ SkScaledImageCache::Unlock(id);
+ }
+
+ /* Input: bitmap+inverse_scale */
+ static ID* FindAndLock(const SkBitmap& src, SkScalar invScaleX, SkScalar invScaleY,
+ SkBitmap* result);
+ static ID* AddAndLock(const SkBitmap& src, SkScalar invScaleX, SkScalar invScaleY,
+ const SkBitmap& result);
+
+ /* Input: bitmap_genID+width+height */
+ static ID* FindAndLock(uint32_t genID, int width, int height, SkBitmap* result);
+
+ static ID* AddAndLock(uint32_t genID, int width, int height, const SkBitmap& result);
+};
+
+class SkMipMapCache {
+public:
+ typedef SkScaledImageCache::ID ID;
+
+ static void Unlock(ID* id) {
+ SkScaledImageCache::Unlock(id);
+ }
+
+ static ID* FindAndLock(const SkBitmap& src, const SkMipMap** result);
+ static ID* AddAndLock(const SkBitmap& src, const SkMipMap* result);
+};
+
+#endif
diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp
index 6a6cc75..0cf4d6c 100644
--- a/src/core/SkBitmapProcState.cpp
+++ b/src/core/SkBitmapProcState.cpp
@@ -1,10 +1,11 @@
-
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
+
+#include "SkBitmapCache.h"
#include "SkBitmapProcState.h"
#include "SkColorPriv.h"
#include "SkFilterProc.h"
@@ -14,7 +15,6 @@
#include "SkBitmapScaler.h"
#include "SkMipMap.h"
#include "SkPixelRef.h"
-#include "SkScaledImageCache.h"
#include "SkImageEncoder.h"
#if !SK_ARM_NEON_IS_NONE
@@ -183,9 +183,8 @@
return false;
}
- fScaledCacheID = SkScaledImageCache::FindAndLock(fOrigBitmap,
- invScaleX, invScaleY,
- &fScaledBitmap);
+ fScaledCacheID = SkBitmapCache::FindAndLock(fOrigBitmap, invScaleX, invScaleY,
+ &fScaledBitmap);
if (fScaledCacheID) {
fScaledBitmap.lockPixels();
if (!fScaledBitmap.getPixels()) {
@@ -216,10 +215,8 @@
}
SkASSERT(NULL != fScaledBitmap.getPixels());
- fScaledCacheID = SkScaledImageCache::AddAndLock(fOrigBitmap,
- invScaleX,
- invScaleY,
- fScaledBitmap);
+ fScaledCacheID = SkBitmapCache::AddAndLock(fOrigBitmap, invScaleX, invScaleY,
+ fScaledBitmap);
if (!fScaledCacheID) {
fScaledBitmap.reset();
return false;
@@ -286,13 +283,12 @@
const SkMipMap* mip = NULL;
SkASSERT(NULL == fScaledCacheID);
- fScaledCacheID = SkScaledImageCache::FindAndLockMip(fOrigBitmap, &mip);
+ fScaledCacheID = SkMipMapCache::FindAndLock(fOrigBitmap, &mip);
if (!fScaledCacheID) {
SkASSERT(NULL == mip);
mip = SkMipMap::Build(fOrigBitmap);
if (mip) {
- fScaledCacheID = SkScaledImageCache::AddAndLockMip(fOrigBitmap,
- mip);
+ fScaledCacheID = SkMipMapCache::AddAndLock(fOrigBitmap, mip);
SkASSERT(mip->getRefCnt() > 1);
mip->unref(); // the cache took a ref
SkASSERT(fScaledCacheID);
@@ -354,9 +350,7 @@
return false;
}
} else {
- fScaledCacheID = SkScaledImageCache::FindAndLock(fOrigBitmap,
- SK_Scalar1, SK_Scalar1,
- &fScaledBitmap);
+ fScaledCacheID = SkBitmapCache::FindAndLock(fOrigBitmap, 1, 1, &fScaledBitmap);
if (fScaledCacheID) {
fScaledBitmap.lockPixels();
if (!fScaledBitmap.getPixels()) {
@@ -376,9 +370,7 @@
// TODO: if fScaled comes back at a different width/height than fOrig,
// we need to update the matrix we are using to sample from this guy.
- fScaledCacheID = SkScaledImageCache::AddAndLock(fOrigBitmap,
- SK_Scalar1, SK_Scalar1,
- fScaledBitmap);
+ fScaledCacheID = SkBitmapCache::AddAndLock(fOrigBitmap, 1, 1, fScaledBitmap);
if (!fScaledCacheID) {
fScaledBitmap.reset();
return false;
diff --git a/src/core/SkScaledImageCache.cpp b/src/core/SkScaledImageCache.cpp
index 3e89293..9e672fe 100644
--- a/src/core/SkScaledImageCache.cpp
+++ b/src/core/SkScaledImageCache.cpp
@@ -260,32 +260,10 @@
////////////////////////////////////////////////////////////////////////////////
-struct GenWHKey : public SkScaledImageCache::Key {
-public:
- GenWHKey(uint32_t genID, SkScalar scaleX, SkScalar scaleY, const SkIRect& bounds)
- : fGenID(genID)
- , fScaleX(scaleX)
- , fScaleY(scaleY)
- , fBounds(bounds) {
- this->init(7 * sizeof(uint32_t));
- }
-
- uint32_t fGenID;
- SkScalar fScaleX;
- SkScalar fScaleY;
- SkIRect fBounds;
-};
-
-SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(uint32_t genID,
- SkScalar scaleX,
- SkScalar scaleY,
- const SkIRect& bounds) {
- return this->findAndLock(GenWHKey(genID, scaleX, scaleY, bounds));
-}
-
/**
This private method is the fully general record finder. All other
- record finders should call this function or the one above. */
+ record finders should call this function or the one above.
+ */
SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(const SkScaledImageCache::Key& key) {
#ifdef USE_HASH
Rec* rec = fHash->find(key);
@@ -299,56 +277,18 @@
return rec;
}
-/**
- This function finds the bounds of the bitmap *within its pixelRef*.
- If the bitmap lacks a pixelRef, it will return an empty rect, since
- that doesn't make sense. This may be a useful enough function that
- it should be somewhere else (in SkBitmap?). */
-static SkIRect get_bounds_from_bitmap(const SkBitmap& bm) {
- if (!(bm.pixelRef())) {
- return SkIRect::MakeEmpty();
- }
- SkIPoint origin = bm.pixelRefOrigin();
- return SkIRect::MakeXYWH(origin.fX, origin.fY, bm.width(), bm.height());
-}
-
-
-SkScaledImageCache::ID* SkScaledImageCache::findAndLock(uint32_t genID,
- int32_t width,
- int32_t height,
- SkBitmap* bitmap) {
- Rec* rec = this->findAndLock(genID, SK_Scalar1, SK_Scalar1,
- SkIRect::MakeWH(width, height));
+SkScaledImageCache::ID* SkScaledImageCache::findAndLock(const Key& key, SkBitmap* result) {
+ Rec* rec = this->findAndLock(key);
if (rec) {
SkASSERT(NULL == rec->fMip);
SkASSERT(rec->fBitmap.pixelRef());
- *bitmap = rec->fBitmap;
+ *result = rec->fBitmap;
}
return rec_to_id(rec);
}
-SkScaledImageCache::ID* SkScaledImageCache::findAndLock(const SkBitmap& orig,
- SkScalar scaleX,
- SkScalar scaleY,
- SkBitmap* scaled) {
- if (0 == scaleX || 0 == scaleY) {
- // degenerate, and the key we use for mipmaps
- return NULL;
- }
- Rec* rec = this->findAndLock(orig.getGenerationID(), scaleX,
- scaleY, get_bounds_from_bitmap(orig));
- if (rec) {
- SkASSERT(NULL == rec->fMip);
- SkASSERT(rec->fBitmap.pixelRef());
- *scaled = rec->fBitmap;
- }
- return rec_to_id(rec);
-}
-
-SkScaledImageCache::ID* SkScaledImageCache::findAndLockMip(const SkBitmap& orig,
- SkMipMap const ** mip) {
- Rec* rec = this->findAndLock(orig.getGenerationID(), 0, 0,
- get_bounds_from_bitmap(orig));
+SkScaledImageCache::ID* SkScaledImageCache::findAndLock(const Key& key, const SkMipMap** mip) {
+ Rec* rec = this->findAndLock(key);
if (rec) {
SkASSERT(rec->fMip);
SkASSERT(NULL == rec->fBitmap.pixelRef());
@@ -385,39 +325,12 @@
return rec_to_id(rec);
}
-SkScaledImageCache::ID* SkScaledImageCache::addAndLock(uint32_t genID,
- int32_t width,
- int32_t height,
- const SkBitmap& bitmap) {
- GenWHKey key(genID, SK_Scalar1, SK_Scalar1, SkIRect::MakeWH(width, height));
- Rec* rec = SkNEW_ARGS(Rec, (key, bitmap));
- return this->addAndLock(rec);
-}
-
-SkScaledImageCache::ID* SkScaledImageCache::addAndLock(const SkBitmap& orig,
- SkScalar scaleX,
- SkScalar scaleY,
- const SkBitmap& scaled) {
- if (0 == scaleX || 0 == scaleY) {
- // degenerate, and the key we use for mipmaps
- return NULL;
- }
- SkIRect bounds = get_bounds_from_bitmap(orig);
- if (bounds.isEmpty()) {
- return NULL;
- }
- GenWHKey key(orig.getGenerationID(), scaleX, scaleY, bounds);
+SkScaledImageCache::ID* SkScaledImageCache::addAndLock(const Key& key, const SkBitmap& scaled) {
Rec* rec = SkNEW_ARGS(Rec, (key, scaled));
return this->addAndLock(rec);
}
-SkScaledImageCache::ID* SkScaledImageCache::addAndLockMip(const SkBitmap& orig,
- const SkMipMap* mip) {
- SkIRect bounds = get_bounds_from_bitmap(orig);
- if (bounds.isEmpty()) {
- return NULL;
- }
- GenWHKey key(orig.getGenerationID(), 0, 0, bounds);
+SkScaledImageCache::ID* SkScaledImageCache::addAndLock(const Key& key, const SkMipMap* mip) {
Rec* rec = SkNEW_ARGS(Rec, (key, mip));
return this->addAndLock(rec);
}
@@ -663,52 +576,24 @@
return gScaledImageCache;
}
-
-SkScaledImageCache::ID* SkScaledImageCache::FindAndLock(
- uint32_t pixelGenerationID,
- int32_t width,
- int32_t height,
- SkBitmap* scaled) {
+SkScaledImageCache::ID* SkScaledImageCache::FindAndLock(const Key& key, SkBitmap* result) {
SkAutoMutexAcquire am(gMutex);
- return get_cache()->findAndLock(pixelGenerationID, width, height, scaled);
+ return get_cache()->findAndLock(key, result);
}
-SkScaledImageCache::ID* SkScaledImageCache::AddAndLock(
- uint32_t pixelGenerationID,
- int32_t width,
- int32_t height,
- const SkBitmap& scaled) {
+SkScaledImageCache::ID* SkScaledImageCache::FindAndLock(const Key& key, SkMipMap const ** mip) {
SkAutoMutexAcquire am(gMutex);
- return get_cache()->addAndLock(pixelGenerationID, width, height, scaled);
+ return get_cache()->findAndLock(key, mip);
}
-
-SkScaledImageCache::ID* SkScaledImageCache::FindAndLock(const SkBitmap& orig,
- SkScalar scaleX,
- SkScalar scaleY,
- SkBitmap* scaled) {
+SkScaledImageCache::ID* SkScaledImageCache::AddAndLock(const Key& key, const SkBitmap& scaled) {
SkAutoMutexAcquire am(gMutex);
- return get_cache()->findAndLock(orig, scaleX, scaleY, scaled);
+ return get_cache()->addAndLock(key, scaled);
}
-SkScaledImageCache::ID* SkScaledImageCache::FindAndLockMip(const SkBitmap& orig,
- SkMipMap const ** mip) {
+SkScaledImageCache::ID* SkScaledImageCache::AddAndLock(const Key& key, const SkMipMap* mip) {
SkAutoMutexAcquire am(gMutex);
- return get_cache()->findAndLockMip(orig, mip);
-}
-
-SkScaledImageCache::ID* SkScaledImageCache::AddAndLock(const SkBitmap& orig,
- SkScalar scaleX,
- SkScalar scaleY,
- const SkBitmap& scaled) {
- SkAutoMutexAcquire am(gMutex);
- return get_cache()->addAndLock(orig, scaleX, scaleY, scaled);
-}
-
-SkScaledImageCache::ID* SkScaledImageCache::AddAndLockMip(const SkBitmap& orig,
- const SkMipMap* mip) {
- SkAutoMutexAcquire am(gMutex);
- return get_cache()->addAndLockMip(orig, mip);
+ return get_cache()->addAndLock(key, mip);
}
void SkScaledImageCache::Unlock(SkScaledImageCache::ID* id) {
diff --git a/src/core/SkScaledImageCache.h b/src/core/SkScaledImageCache.h
index 19da671..3f44e26 100644
--- a/src/core/SkScaledImageCache.h
+++ b/src/core/SkScaledImageCache.h
@@ -73,26 +73,12 @@
* instance of this cache.
*/
- static ID* FindAndLock(uint32_t pixelGenerationID,
- int32_t width,
- int32_t height,
- SkBitmap* returnedBitmap);
-
- static ID* FindAndLock(const SkBitmap& original, SkScalar scaleX,
- SkScalar scaleY, SkBitmap* returnedBitmap);
- static ID* FindAndLockMip(const SkBitmap& original,
- SkMipMap const** returnedMipMap);
-
-
- static ID* AddAndLock(uint32_t pixelGenerationID,
- int32_t width,
- int32_t height,
- const SkBitmap& bitmap);
-
- static ID* AddAndLock(const SkBitmap& original, SkScalar scaleX,
- SkScalar scaleY, const SkBitmap& bitmap);
- static ID* AddAndLockMip(const SkBitmap& original, const SkMipMap* mipMap);
-
+ static ID* FindAndLock(const Key&, SkBitmap* result);
+ static ID* AddAndLock(const Key&, const SkBitmap& result);
+
+ static ID* FindAndLock(const Key&, const SkMipMap** result);
+ static ID* AddAndLock(const Key&, const SkMipMap* result);
+
static void Unlock(ID*);
static size_t GetTotalBytesUsed();
@@ -126,39 +112,17 @@
* that pushes the total bytesUsed over the limit. Note: The limit can be
* changed at runtime with setTotalByteLimit.
*/
- SkScaledImageCache(size_t byteLimit);
-
+ explicit SkScaledImageCache(size_t byteLimit);
~SkScaledImageCache();
/**
- * Search the cache for a matching bitmap (using generationID,
- * width, and height as a search key). If found, return it in
- * returnedBitmap, and return its ID pointer. Use the returned
- * ptr to unlock the cache when you are done using
- * returnedBitmap.
+ * Search the cache for a matching key. If found, return its bitmap and return its ID pointer.
+ * Use the returned ID to unlock the cache when you are done using outBitmap.
*
- * If a match is not found, returnedBitmap will be unmodifed, and
- * NULL will be returned.
- *
- * This is used if there is no scaling or subsetting, for example
- * by SkLazyPixelRef.
+ * If a match is not found, outBitmap will be unmodifed, and NULL will be returned.
*/
- ID* findAndLock(uint32_t pixelGenerationID, int32_t width, int32_t height,
- SkBitmap* returnedBitmap);
-
- /**
- * Search the cache for a scaled version of original. If found,
- * return it in returnedBitmap, and return its ID pointer. Use
- * the returned ptr to unlock the cache when you are done using
- * returnedBitmap.
- *
- * If a match is not found, returnedBitmap will be unmodifed, and
- * NULL will be returned.
- */
- ID* findAndLock(const SkBitmap& original, SkScalar scaleX,
- SkScalar scaleY, SkBitmap* returnedBitmap);
- ID* findAndLockMip(const SkBitmap& original,
- SkMipMap const** returnedMipMap);
+ ID* findAndLock(const Key& key, SkBitmap* outBitmap);
+ ID* findAndLock(const Key& key, const SkMipMap** returnedMipMap);
/**
* To add a new bitmap (or mipMap) to the cache, call
@@ -168,11 +132,8 @@
* Use (generationID, width, and height) or (original, scaleX,
* scaleY) or (original) as a search key
*/
- ID* addAndLock(uint32_t pixelGenerationID, int32_t width, int32_t height,
- const SkBitmap& bitmap);
- ID* addAndLock(const SkBitmap& original, SkScalar scaleX,
- SkScalar scaleY, const SkBitmap& bitmap);
- ID* addAndLockMip(const SkBitmap& original, const SkMipMap* mipMap);
+ ID* addAndLock(const Key&, const SkBitmap& bitmap);
+ ID* addAndLock(const Key&, const SkMipMap* mipMap);
/**
* Given a non-null ID ptr returned by either findAndLock or addAndLock,
@@ -224,8 +185,6 @@
size_t fSingleAllocationByteLimit;
int fCount;
- Rec* findAndLock(uint32_t generationID, SkScalar sx, SkScalar sy,
- const SkIRect& bounds);
Rec* findAndLock(const Key& key);
ID* addAndLock(Rec* rec);
diff --git a/src/lazy/SkCachingPixelRef.cpp b/src/lazy/SkCachingPixelRef.cpp
index 97503e5..c596828 100644
--- a/src/lazy/SkCachingPixelRef.cpp
+++ b/src/lazy/SkCachingPixelRef.cpp
@@ -6,7 +6,7 @@
*/
#include "SkCachingPixelRef.h"
-#include "SkScaledImageCache.h"
+#include "SkBitmapCache.h"
bool SkCachingPixelRef::Install(SkImageGenerator* generator,
SkBitmap* dst) {
@@ -48,10 +48,8 @@
const SkImageInfo& info = this->info();
SkBitmap bitmap;
SkASSERT(NULL == fScaledCacheId);
- fScaledCacheId = SkScaledImageCache::FindAndLock(this->getGenerationID(),
- info.fWidth,
- info.fHeight,
- &bitmap);
+ fScaledCacheId = SkBitmapCache::FindAndLock(this->getGenerationID(), info.fWidth, info.fHeight,
+ &bitmap);
if (NULL == fScaledCacheId) {
// Cache has been purged, must re-decode.
if (!bitmap.allocPixels(info, fRowBytes)) {
@@ -63,10 +61,8 @@
fErrorInDecoding = true;
return false;
}
- fScaledCacheId = SkScaledImageCache::AddAndLock(this->getGenerationID(),
- info.fWidth,
- info.fHeight,
- bitmap);
+ fScaledCacheId = SkBitmapCache::AddAndLock(this->getGenerationID(),
+ info.fWidth, info.fHeight, bitmap);
SkASSERT(fScaledCacheId != NULL);
}