[Reland] More SkColorSpaceXformer caching

  * apply(SkColorFilter*)
  * apply(SkImage*)

Also add purge logic to minimize caching scope.

Change-Id: I295d20f760f8be0c3746858d6f9c73e351f10a36
Reviewed-on: https://skia-review.googlesource.com/22030
Commit-Queue: Florin Malita <fmalita@chromium.org>
Reviewed-by: Mike Reed <reed@google.com>
diff --git a/src/core/SkColorSpaceXformer.h b/src/core/SkColorSpaceXformer.h
index fce8d03..5fa4d83 100644
--- a/src/core/SkColorSpaceXformer.h
+++ b/src/core/SkColorSpaceXformer.h
@@ -41,10 +41,24 @@
 private:
     SkColorSpaceXformer(sk_sp<SkColorSpace> dst, std::unique_ptr<SkColorSpaceXform> fromSRGB);
 
+    template <typename T>
+    using Cache = SkTHashMap<sk_sp<T>, sk_sp<T>>;
+
+    template <typename T>
+    sk_sp<T> cachedApply(const T*, Cache<T>*, sk_sp<T> (*)(const T*, SkColorSpaceXformer*));
+
+    void purgeCaches();
+
+    class AutoCachePurge;
+
     sk_sp<SkColorSpace>                fDst;
     std::unique_ptr<SkColorSpaceXform> fFromSRGB;
 
-    SkTHashMap<uint32_t, sk_sp<SkImageFilter>> fFilterCache;
+    size_t fReentryCount; // tracks the number of nested apply() calls for cache purging.
+
+    Cache<SkImage      > fImageCache;
+    Cache<SkColorFilter> fColorFilterCache;
+    Cache<SkImageFilter> fImageFilterCache;
 };
 
 #endif