only create new instance if needed for colorspacexformer

just an experiment to address performance when imagefilters are cached.

Bug: skia:
Change-Id: Ic1033c897d0a569b46a339fb3ae7f8f961882953
Reviewed-on: https://skia-review.googlesource.com/21395
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp
index 4918859..e46be12 100644
--- a/src/effects/SkAlphaThresholdFilter.cpp
+++ b/src/effects/SkAlphaThresholdFilter.cpp
@@ -8,6 +8,7 @@
 #include "SkAlphaThresholdFilter.h"
 
 #include "SkBitmap.h"
+#include "SkColorSpaceXformer.h"
 #include "SkReadBuffer.h"
 #include "SkSpecialImage.h"
 #include "SkWriteBuffer.h"
@@ -262,13 +263,12 @@
 sk_sp<SkImageFilter> SkAlphaThresholdFilterImpl::onMakeColorSpace(SkColorSpaceXformer* xformer)
 const {
     SkASSERT(1 == this->countInputs());
-    if (!this->getInput(0)) {
-        return sk_ref_sp(const_cast<SkAlphaThresholdFilterImpl*>(this));
+    sk_sp<SkImageFilter> input = xformer->apply(this->getInput(0));
+    if (input.get() != this->getInput(0)) {
+        return SkAlphaThresholdFilter::Make(fRegion, fInnerThreshold, fOuterThreshold,
+                                            std::move(input), this->getCropRectIfSet());
     }
-
-    sk_sp<SkImageFilter> input = this->getInput(0)->makeColorSpace(xformer);
-    return SkAlphaThresholdFilter::Make(fRegion, fInnerThreshold, fOuterThreshold,
-                                        std::move(input), this->getCropRectIfSet());
+    return this->refMe();
 }
 
 #ifndef SK_IGNORE_TO_STRING
diff --git a/src/effects/SkArithmeticImageFilter.cpp b/src/effects/SkArithmeticImageFilter.cpp
index 86e66ef..5201f9d 100644
--- a/src/effects/SkArithmeticImageFilter.cpp
+++ b/src/effects/SkArithmeticImageFilter.cpp
@@ -7,6 +7,7 @@
 
 #include "SkArithmeticImageFilter.h"
 #include "SkCanvas.h"
+#include "SkColorSpaceXformer.h"
 #include "SkNx.h"
 #include "SkReadBuffer.h"
 #include "SkSpecialImage.h"
@@ -454,17 +455,14 @@
 sk_sp<SkImageFilter> ArithmeticImageFilterImpl::onMakeColorSpace(SkColorSpaceXformer* xformer)
 const {
     SkASSERT(2 == this->countInputs());
-    if (!this->getInput(0) && !this->getInput(1)) {
-        return sk_ref_sp(const_cast<ArithmeticImageFilterImpl*>(this));
+    auto background = xformer->apply(this->getInput(0));
+    auto foreground = xformer->apply(this->getInput(1));
+    if (background.get() != this->getInput(0) || foreground.get() != this->getInput(1)) {
+        return SkArithmeticImageFilter::Make(fK[0], fK[1], fK[2], fK[3], fEnforcePMColor,
+                                             std::move(background), std::move(foreground),
+                                             getCropRectIfSet());
     }
-
-    sk_sp<SkImageFilter> background =
-            this->getInput(0) ? this->getInput(0)->makeColorSpace(xformer) : nullptr;
-    sk_sp<SkImageFilter> foreground =
-            this->getInput(1) ? this->getInput(1)->makeColorSpace(xformer) : nullptr;
-    return SkArithmeticImageFilter::Make(fK[0], fK[1], fK[2], fK[3], fEnforcePMColor,
-                                         std::move(background), std::move(foreground),
-                                         getCropRectIfSet());
+    return this->refMe();
 }
 
 #ifndef SK_IGNORE_TO_STRING
diff --git a/src/effects/SkColorFilterImageFilter.cpp b/src/effects/SkColorFilterImageFilter.cpp
index 75dccfe..6e81bf3 100644
--- a/src/effects/SkColorFilterImageFilter.cpp
+++ b/src/effects/SkColorFilterImageFilter.cpp
@@ -121,12 +121,13 @@
 const {
     SkASSERT(1 == this->countInputs());
 
-    sk_sp<SkImageFilter> input =
-            this->getInput(0) ? this->getInput(0)->makeColorSpace(xformer) : nullptr;
-    sk_sp<SkColorFilter> colorFilter = xformer->apply(fColorFilter.get());
-
-    return SkColorFilterImageFilter::Make(std::move(colorFilter), std::move(input),
-                                          this->getCropRectIfSet());
+    sk_sp<SkImageFilter> input = xformer->apply(this->getInput(0));
+    auto colorFilter = xformer->apply(fColorFilter.get());
+    if (this->getInput(0) != input.get() || fColorFilter != colorFilter) {
+        return SkColorFilterImageFilter::Make(std::move(colorFilter), std::move(input),
+                                              this->getCropRectIfSet());
+    }
+    return this->refMe();
 }
 
 bool SkColorFilterImageFilter::onIsColorFilterNode(SkColorFilter** filter) const {
diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp
index 148db93..0860df7 100644
--- a/src/effects/SkColorMatrixFilter.cpp
+++ b/src/effects/SkColorMatrixFilter.cpp
@@ -40,7 +40,11 @@
 
     // Overriding this method is the class' raison d'etre.
     sk_sp<SkColorFilter> onMakeColorSpace(SkColorSpaceXformer* xformer) const override {
-        return sk_make_sp<SkLightingColorFilter>(xformer->apply(fMul), xformer->apply(fAdd));
+        SkColor add = xformer->apply(fAdd);
+        if (add != fAdd) {
+            return sk_make_sp<SkLightingColorFilter>(fMul, add);
+        }
+        return this->INHERITED::onMakeColorSpace(xformer);
     }
 
     // Let fMatrixFilter handle all the other calls directly.
@@ -74,6 +78,8 @@
 private:
     SkColor              fMul, fAdd;
     sk_sp<SkColorFilter> fMatrixFilter;
+
+    typedef SkColorFilter INHERITED;
 };
 
 sk_sp<SkColorFilter> SkColorMatrixFilter::MakeLightingFilter(SkColor mul, SkColor add) {
diff --git a/src/effects/SkComposeImageFilter.cpp b/src/effects/SkComposeImageFilter.cpp
index 9397c83..ad841d0 100644
--- a/src/effects/SkComposeImageFilter.cpp
+++ b/src/effects/SkComposeImageFilter.cpp
@@ -6,7 +6,7 @@
  */
 
 #include "SkComposeImageFilter.h"
-
+#include "SkColorSpaceXformer.h"
 #include "SkReadBuffer.h"
 #include "SkSpecialImage.h"
 #include "SkWriteBuffer.h"
@@ -64,8 +64,12 @@
 sk_sp<SkImageFilter> SkComposeImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
     SkASSERT(2 == this->countInputs() && this->getInput(0) && this->getInput(1));
 
-    return SkComposeImageFilter::Make(this->getInput(0)->makeColorSpace(xformer),
-                                      this->getInput(1)->makeColorSpace(xformer));
+    auto input0 = xformer->apply(this->getInput(0));
+    auto input1 = xformer->apply(this->getInput(1));
+    if (input0.get() != this->getInput(0) || input1.get() != this->getInput(1)) {
+        return SkComposeImageFilter::Make(std::move(input0), std::move(input1));
+    }
+    return this->refMe();
 }
 
 SkIRect SkComposeImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index dc85088..90756a7 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -8,6 +8,7 @@
 #include "SkDisplacementMapEffect.h"
 
 #include "SkBitmap.h"
+#include "SkColorSpaceXformer.h"
 #include "SkReadBuffer.h"
 #include "SkSpecialImage.h"
 #include "SkWriteBuffer.h"
@@ -358,19 +359,17 @@
 
 sk_sp<SkImageFilter> SkDisplacementMapEffect::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
     SkASSERT(2 == this->countInputs());
-    if (!this->getInput(1)) {
-        return sk_ref_sp(const_cast<SkDisplacementMapEffect*>(this));
-    }
-
     // Intentionally avoid xforming the displacement filter.  The values will be used as
     // offsets, not as colors.
     sk_sp<SkImageFilter> displacement = sk_ref_sp(const_cast<SkImageFilter*>(this->getInput(0)));
-    sk_sp<SkImageFilter> color =
-            this->getInput(1) ? this->getInput(1)->makeColorSpace(xformer) : nullptr;
+    sk_sp<SkImageFilter> color = xformer->apply(this->getInput(1));
 
-    return SkDisplacementMapEffect::Make(fXChannelSelector, fYChannelSelector, fScale,
-                                         std::move(displacement), std::move(color),
-                                         this->getCropRectIfSet());
+    if (color.get() != this->getInput(1)) {
+        return SkDisplacementMapEffect::Make(fXChannelSelector, fYChannelSelector, fScale,
+                                             std::move(displacement), std::move(color),
+                                             this->getCropRectIfSet());
+    }
+    return this->refMe();
 }
 
 SkRect SkDisplacementMapEffect::computeFastBounds(const SkRect& src) const {
diff --git a/src/effects/SkDropShadowImageFilter.cpp b/src/effects/SkDropShadowImageFilter.cpp
index 9d778e0..8525573 100644
--- a/src/effects/SkDropShadowImageFilter.cpp
+++ b/src/effects/SkDropShadowImageFilter.cpp
@@ -116,9 +116,12 @@
 
     sk_sp<SkImageFilter> input =
             this->getInput(0) ? this->getInput(0)->makeColorSpace(xformer) : nullptr;
-
-    return SkDropShadowImageFilter::Make(fDx, fDy, fSigmaX, fSigmaY, xformer->apply(fColor),
-                                         fShadowMode, std::move(input), this->getCropRectIfSet());
+    SkColor color = xformer->apply(fColor);
+    if (input.get() != this->getInput(0) || color != fColor) {
+        return SkDropShadowImageFilter::Make(fDx, fDy, fSigmaX, fSigmaY, color,
+                                             fShadowMode, input, this->getCropRectIfSet());
+    }
+    return this->refMe();
 }
 
 SkRect SkDropShadowImageFilter::computeFastBounds(const SkRect& src) const {
diff --git a/src/effects/SkImageSource.cpp b/src/effects/SkImageSource.cpp
index e051160..cd2fb51 100644
--- a/src/effects/SkImageSource.cpp
+++ b/src/effects/SkImageSource.cpp
@@ -135,7 +135,11 @@
 sk_sp<SkImageFilter> SkImageSource::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
     SkASSERT(0 == this->countInputs());
 
-    return SkImageSource::Make(xformer->apply(fImage.get()), fSrcRect, fDstRect, fFilterQuality);
+    auto image = xformer->apply(fImage.get());
+    if (image != fImage) {
+        return SkImageSource::Make(image, fSrcRect, fDstRect, fFilterQuality);
+    }
+    return this->refMe();
 }
 
 SkRect SkImageSource::computeFastBounds(const SkRect& src) const {
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index be87286..7b72fcd 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -1341,11 +1341,13 @@
 sk_sp<SkImageFilter> SkDiffuseLightingImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer)
 const {
     SkASSERT(1 == this->countInputs());
-    sk_sp<SkImageFilter> input =
-            this->getInput(0) ? this->getInput(0)->onMakeColorSpace(xformer) : nullptr;
-    return SkDiffuseLightingImageFilter::Make(this->light()->makeColorSpace(xformer),
-                                              255.0f * this->surfaceScale(), fKD, std::move(input),
-                                              this->getCropRectIfSet());
+    auto input = xformer->apply(this->getInput(0));
+    auto light = this->light()->makeColorSpace(xformer);
+    if (input.get() != this->getInput(0) || light.get() != this->light()) {
+        return SkDiffuseLightingImageFilter::Make(std::move(light), 255.0f * this->surfaceScale(),
+                                                  fKD, std::move(input), this->getCropRectIfSet());
+    }
+    return this->refMe();
 }
 
 #ifndef SK_IGNORE_TO_STRING
@@ -1495,11 +1497,14 @@
 const {
     SkASSERT(1 == this->countInputs());
 
-    sk_sp<SkImageFilter> input =
-            this->getInput(0) ? this->getInput(0)->onMakeColorSpace(xformer) : nullptr;
-    return SkSpecularLightingImageFilter::Make(this->light()->makeColorSpace(xformer),
-                                               255.0f * this->surfaceScale(), fKS, fShininess,
-                                               std::move(input), this->getCropRectIfSet());
+    auto input = xformer->apply(this->getInput(0));
+    auto light = this->light()->makeColorSpace(xformer);
+    if (input.get() != this->getInput(0) || light.get() != this->light()) {
+        return SkSpecularLightingImageFilter::Make(std::move(light),
+                                                   255.0f * this->surfaceScale(), fKS, fShininess,
+                                                   std::move(input), this->getCropRectIfSet());
+    }
+    return this->refMe();
 }
 
 #ifndef SK_IGNORE_TO_STRING
diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp
index 76e9b3e..90e0a5c 100644
--- a/src/effects/SkMagnifierImageFilter.cpp
+++ b/src/effects/SkMagnifierImageFilter.cpp
@@ -9,6 +9,7 @@
 
 #include "SkBitmap.h"
 #include "SkColorPriv.h"
+#include "SkColorSpaceXformer.h"
 #include "SkReadBuffer.h"
 #include "SkSpecialImage.h"
 #include "SkWriteBuffer.h"
@@ -438,13 +439,12 @@
 
 sk_sp<SkImageFilter> SkMagnifierImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
     SkASSERT(1 == this->countInputs());
-    if (!this->getInput(0)) {
-        return sk_ref_sp(const_cast<SkMagnifierImageFilter*>(this));
+    auto input = xformer->apply(this->getInput(0));
+    if (input.get() != this->getInput(0)) {
+        return SkMagnifierImageFilter::Make(fSrcRect, fInset, std::move(input),
+                                            this->getCropRectIfSet());
     }
-
-    sk_sp<SkImageFilter> input = this->getInput(0)->makeColorSpace(xformer);
-    return SkMagnifierImageFilter::Make(fSrcRect, fInset, std::move(input),
-                                        this->getCropRectIfSet());
+    return this->refMe();
 }
 
 #ifndef SK_IGNORE_TO_STRING
diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp
index e92f072..b94ece5 100644
--- a/src/effects/SkMatrixConvolutionImageFilter.cpp
+++ b/src/effects/SkMatrixConvolutionImageFilter.cpp
@@ -8,6 +8,7 @@
 #include "SkMatrixConvolutionImageFilter.h"
 #include "SkBitmap.h"
 #include "SkColorPriv.h"
+#include "SkColorSpaceXformer.h"
 #include "SkReadBuffer.h"
 #include "SkSpecialImage.h"
 #include "SkWriteBuffer.h"
@@ -384,14 +385,14 @@
 sk_sp<SkImageFilter> SkMatrixConvolutionImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer)
 const {
     SkASSERT(1 == this->countInputs());
-    if (!this->getInput(0)) {
-        return sk_ref_sp(const_cast<SkMatrixConvolutionImageFilter*>(this));
-    }
 
-    sk_sp<SkImageFilter> input = this->getInput(0)->makeColorSpace(xformer);
-    return SkMatrixConvolutionImageFilter::Make(fKernelSize, fKernel, fGain, fBias, fKernelOffset,
-                                                fTileMode, fConvolveAlpha, std::move(input),
-                                                this->getCropRectIfSet());
+    sk_sp<SkImageFilter> input = xformer->apply(this->getInput(0));
+    if (input.get() != this->getInput(0)) {
+        return SkMatrixConvolutionImageFilter::Make(fKernelSize, fKernel, fGain, fBias,
+                                                    fKernelOffset, fTileMode, fConvolveAlpha,
+                                                    std::move(input), this->getCropRectIfSet());
+    }
+    return this->refMe();
 }
 
 SkIRect SkMatrixConvolutionImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
diff --git a/src/effects/SkMergeImageFilter.cpp b/src/effects/SkMergeImageFilter.cpp
index e109880..0e882eb 100644
--- a/src/effects/SkMergeImageFilter.cpp
+++ b/src/effects/SkMergeImageFilter.cpp
@@ -95,12 +95,19 @@
 
 sk_sp<SkImageFilter> SkMergeImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
     SkSTArray<5, sk_sp<SkImageFilter>> inputs(this->countInputs());
+    bool changed = false;
     for (int i = 0; i < this->countInputs(); i++) {
         inputs.push_back(this->getInput(i) ? this->getInput(i)->makeColorSpace(xformer) : nullptr);
+        if (inputs[i].get() != this->getInput(i)) {
+            changed = true;
+        }
     }
 
-    return SkMergeImageFilter::Make(inputs.begin(), this->countInputs(),
-                                    this->getCropRectIfSet());
+    if (changed) {
+        return SkMergeImageFilter::Make(inputs.begin(), this->countInputs(),
+                                        this->getCropRectIfSet());
+    }
+    return this->refMe();
 }
 
 sk_sp<SkFlattenable> SkMergeImageFilter::CreateProc(SkReadBuffer& buffer) {
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index fd928de..a148bb3 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -9,6 +9,7 @@
 
 #include "SkBitmap.h"
 #include "SkColorPriv.h"
+#include "SkColorSpaceXformer.h"
 #include "SkOpts.h"
 #include "SkReadBuffer.h"
 #include "SkRect.h"
@@ -640,16 +641,15 @@
                                           dst, &source->props());
 }
 
-sk_sp<SkImageFilter> SkMorphologyImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
+sk_sp<SkImageFilter> SkMorphologyImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const{
     SkASSERT(1 == this->countInputs());
-    if (!this->getInput(0)) {
-        return sk_ref_sp(const_cast<SkMorphologyImageFilter*>(this));
+    auto input = xformer->apply(this->getInput(0));
+    if (input.get() != this->getInput(0)) {
+        return (SkMorphologyImageFilter::kDilate_Op == this->op())
+                ? SkDilateImageFilter::Make(fRadius.width(), fRadius.height(), std::move(input),
+                                            this->getCropRectIfSet())
+                : SkErodeImageFilter::Make(fRadius.width(), fRadius.height(), std::move(input),
+                                           this->getCropRectIfSet());
     }
-
-    sk_sp<SkImageFilter> input = this->getInput(0)->makeColorSpace(xformer);
-    return (SkMorphologyImageFilter::kDilate_Op == this->op())
-            ? SkDilateImageFilter::Make(fRadius.width(), fRadius.height(), std::move(input),
-                                        this->getCropRectIfSet())
-            : SkErodeImageFilter::Make(fRadius.width(), fRadius.height(), std::move(input),
-                                       this->getCropRectIfSet());
+    return this->refMe();
 }
diff --git a/src/effects/SkOffsetImageFilter.cpp b/src/effects/SkOffsetImageFilter.cpp
index 973b2a6..f25ffdc 100644
--- a/src/effects/SkOffsetImageFilter.cpp
+++ b/src/effects/SkOffsetImageFilter.cpp
@@ -6,7 +6,7 @@
  */
 
 #include "SkOffsetImageFilter.h"
-
+#include "SkColorSpaceXformer.h"
 #include "SkCanvas.h"
 #include "SkMatrix.h"
 #include "SkPaint.h"
@@ -75,13 +75,13 @@
 
 sk_sp<SkImageFilter> SkOffsetImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
     SkASSERT(1 == this->countInputs());
-    if (!this->getInput(0)) {
-        return sk_ref_sp(const_cast<SkOffsetImageFilter*>(this));
-    }
 
-    sk_sp<SkImageFilter> input = this->getInput(0)->makeColorSpace(xformer);
-    return SkOffsetImageFilter::Make(fOffset.fX, fOffset.fY, std::move(input),
-                                     this->getCropRectIfSet());
+    auto input = xformer->apply(this->getInput(0));
+    if (input.get() != this->getInput(0)) {
+        return SkOffsetImageFilter::Make(fOffset.fX, fOffset.fY, std::move(input),
+                                         this->getCropRectIfSet());
+    }
+    return this->refMe();
 }
 
 SkRect SkOffsetImageFilter::computeFastBounds(const SkRect& src) const {
diff --git a/src/effects/SkPaintImageFilter.cpp b/src/effects/SkPaintImageFilter.cpp
index c793858..5e47e82 100644
--- a/src/effects/SkPaintImageFilter.cpp
+++ b/src/effects/SkPaintImageFilter.cpp
@@ -70,7 +70,11 @@
 }
 
 sk_sp<SkImageFilter> SkPaintImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
-    return SkPaintImageFilter::Make(xformer->apply(fPaint), this->getCropRectIfSet());
+    SkPaint paint = xformer->apply(fPaint);
+    if (paint != fPaint) {
+        return SkPaintImageFilter::Make(paint, this->getCropRectIfSet());
+    }
+    return this->refMe();
 }
 
 bool SkPaintImageFilter::affectsTransparentBlack() const {
diff --git a/src/effects/SkTileImageFilter.cpp b/src/effects/SkTileImageFilter.cpp
index 262ad65..050e813 100644
--- a/src/effects/SkTileImageFilter.cpp
+++ b/src/effects/SkTileImageFilter.cpp
@@ -6,7 +6,7 @@
  */
 
 #include "SkTileImageFilter.h"
-
+#include "SkColorSpaceXformer.h"
 #include "SkCanvas.h"
 #include "SkImage.h"
 #include "SkMatrix.h"
@@ -118,12 +118,12 @@
 
 sk_sp<SkImageFilter> SkTileImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
     SkASSERT(1 == this->countInputs());
-    if (!this->getInput(0)) {
-        return sk_ref_sp(const_cast<SkTileImageFilter*>(this));
-    }
 
-    sk_sp<SkImageFilter> input = this->getInput(0)->makeColorSpace(xformer);
-    return SkTileImageFilter::Make(fSrcRect, fDstRect, std::move(input));
+    auto input = xformer->apply(this->getInput(0));
+    if (input.get() != this->getInput(0)) {
+        return SkTileImageFilter::Make(fSrcRect, fDstRect, std::move(input));
+    }
+    return this->refMe();
 }
 
 SkIRect SkTileImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
index 18d52f9..f0c70a2 100644
--- a/src/effects/SkXfermodeImageFilter.cpp
+++ b/src/effects/SkXfermodeImageFilter.cpp
@@ -9,6 +9,7 @@
 #include "SkArithmeticImageFilter.h"
 #include "SkCanvas.h"
 #include "SkColorPriv.h"
+#include "SkColorSpaceXformer.h"
 #include "SkReadBuffer.h"
 #include "SkSpecialImage.h"
 #include "SkSpecialSurface.h"
@@ -174,17 +175,13 @@
 sk_sp<SkImageFilter> SkXfermodeImageFilter_Base::onMakeColorSpace(SkColorSpaceXformer* xformer)
 const {
     SkASSERT(2 == this->countInputs());
-    if (!this->getInput(0) && !this->getInput(1)) {
-        return sk_ref_sp(const_cast<SkXfermodeImageFilter_Base*>(this));
+    auto background = xformer->apply(this->getInput(0));
+    auto foreground = xformer->apply(this->getInput(1));
+    if (background.get() != this->getInput(0) || foreground.get() != this->getInput(1)) {
+        return SkXfermodeImageFilter::Make(fMode, std::move(background), std::move(foreground),
+                                           this->getCropRectIfSet());
     }
-
-    sk_sp<SkImageFilter> background =
-            this->getInput(0) ? this->getInput(0)->makeColorSpace(xformer) : nullptr;
-    sk_sp<SkImageFilter> foreground =
-            this->getInput(1) ? this->getInput(1)->makeColorSpace(xformer) : nullptr;
-
-    return SkXfermodeImageFilter::Make(fMode, std::move(background), std::move(foreground),
-                                       this->getCropRectIfSet());
+    return this->refMe();
 }
 
 void SkXfermodeImageFilter_Base::drawForeground(SkCanvas* canvas, SkSpecialImage* img,