From 39e085559ddbd088866abdf50a48f7ab5b283830 Mon Sep 17 00:00:00 2001 From: Florin Malita Date: Thu, 6 Jul 2017 14:16:18 -0400 Subject: [PATCH] Add an SkColorSpaceXformer image filter cache The cache is scoped with the SkColorSpaceXformer object. This ensures we're not transforming nodes with a degree > 1 multiple times, and preserves the DAG topology. Change-Id: I0b072cdac95f9f1c34e0565ed4f258aba986e1ae Reviewed-on: https://skia-review.googlesource.com/21726 Commit-Queue: Florin Malita Reviewed-by: Mike Reed --- src/core/SkColorSpaceXformer.cpp | 16 +++++++++++++++- src/core/SkColorSpaceXformer.h | 22 +++++++++++++++++----- src/effects/SkColorMatrixFilter.cpp | 1 + tests/ImageFilterTest.cpp | 3 +-- tests/QuickRejectTest.cpp | 1 + 5 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/core/SkColorSpaceXformer.cpp b/src/core/SkColorSpaceXformer.cpp index 1e5206e183..301a7f1e79 100644 --- a/src/core/SkColorSpaceXformer.cpp +++ b/src/core/SkColorSpaceXformer.cpp @@ -10,12 +10,15 @@ #include "SkColorSpaceXform_Base.h" #include "SkDrawLooper.h" #include "SkGradientShader.h" +#include "SkImage.h" #include "SkImage_Base.h" #include "SkImageFilter.h" #include "SkImagePriv.h" #include "SkMakeUnique.h" #include "SkShaderBase.h" +SkColorSpaceXformer::~SkColorSpaceXformer() {} + std::unique_ptr SkColorSpaceXformer::Make(sk_sp dst) { std::unique_ptr fromSRGB = SkColorSpaceXform_Base::New( SkColorSpace::MakeSRGB().get(), dst.get(), SkTransferFunctionBehavior::kIgnore); @@ -50,7 +53,18 @@ sk_sp SkColorSpaceXformer::apply(const SkColorFilter* colorFilter } sk_sp SkColorSpaceXformer::apply(const SkImageFilter* imageFilter) { - return imageFilter ? imageFilter->makeColorSpace(this) : nullptr; + if (!imageFilter) { + return nullptr; + } + + if (auto* xformedFilter = fFilterCache.find(imageFilter->fUniqueID)) { + return sk_ref_sp(xformedFilter->get()); + } + + auto xformedFilter = imageFilter->makeColorSpace(this); + fFilterCache.set(imageFilter->fUniqueID, xformedFilter); + + return xformedFilter; } sk_sp SkColorSpaceXformer::apply(const SkShader* shader) { diff --git a/src/core/SkColorSpaceXformer.h b/src/core/SkColorSpaceXformer.h index f780071789..75db04022f 100644 --- a/src/core/SkColorSpaceXformer.h +++ b/src/core/SkColorSpaceXformer.h @@ -8,15 +8,25 @@ #ifndef SkColorSpaceXformer_DEFINED #define SkColorSpaceXformer_DEFINED -#include "SkColorSpaceXform.h" -#include "SkImage.h" -#include "SkShader.h" -#include "SkImageFilter.h" +#include "SkColor.h" +#include "SkRefCnt.h" +#include "SkTHash.h" + +class SkBitmap; +class SkColorFilter; +class SkColorSpace; +class SkColorSpaceXform; +class SkImage; +class SkImageFilter; +class SkPaint; +class SkShader; class SkColorSpaceXformer : public SkNoncopyable { public: static std::unique_ptr Make(sk_sp dst); + ~SkColorSpaceXformer(); + sk_sp apply(const SkImage*); sk_sp apply(const SkBitmap&); sk_sp apply(const SkColorFilter*); @@ -29,10 +39,12 @@ public: sk_sp dst() const { return fDst; } private: - SkColorSpaceXformer() {} + SkColorSpaceXformer() = default; sk_sp fDst; std::unique_ptr fFromSRGB; + + SkTHashMap> fFilterCache; }; #endif diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp index 0860df7340..0bd6c2ca68 100644 --- a/src/effects/SkColorMatrixFilter.cpp +++ b/src/effects/SkColorMatrixFilter.cpp @@ -6,6 +6,7 @@ */ #include "SkColorMatrixFilter.h" +#include "SkColorSpace.h" #include "SkColorSpaceXformer.h" #if SK_SUPPORT_GPU #include "GrFragmentProcessor.h" diff --git a/tests/ImageFilterTest.cpp b/tests/ImageFilterTest.cpp index c6d184dfea..69b31f184c 100644 --- a/tests/ImageFilterTest.cpp +++ b/tests/ImageFilterTest.cpp @@ -1920,6 +1920,5 @@ DEF_TEST(ImageFilterColorSpaceDAG, reporter) { auto xformer = SkColorSpaceXformer::Make(SkColorSpace::MakeSRGB()); auto xformedFilter = xformer->apply(complexFilter.get()); - // FIXME: clone count should be 1 at this point. - REPORTER_ASSERT(reporter, filter->cloneCount() == 2u); + REPORTER_ASSERT(reporter, filter->cloneCount() == 1u); } diff --git a/tests/QuickRejectTest.cpp b/tests/QuickRejectTest.cpp index b705253e34..d7d330f750 100644 --- a/tests/QuickRejectTest.cpp +++ b/tests/QuickRejectTest.cpp @@ -6,6 +6,7 @@ */ #include "SkArenaAlloc.h" +#include "SkBitmap.h" #include "SkCanvas.h" #include "SkColorSpaceXformer.h" #include "SkDrawLooper.h"