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);