Reland "[skif] Use FilterResult::applyColorFilter in SkColorFilterImageFilter"

This reverts commit 81eb6b2ae5c839594083bf053944252d77932c92.

Reason for revert: suppressions and sampling issues landed earlier

Original change's description:
> Revert "[skif] Use FilterResult::applyColorFilter in SkColorFilterImageFilter"
>
> This reverts commit 3e1b2b15296fe145af69847a98418cf50e0615f3.
>
> Reason for revert: flutter unit test failures and some weird gold images.
>
> Original change's description:
> > [skif] Use FilterResult::applyColorFilter in SkColorFilterImageFilter
> >
> > Unless necessitated for correctness, e.g. intermixing crops with
> > transforms and transparency-affecting color filters, color filter
> > image filters will compose with the FilterResult and avoid producing
> > an intermediate render pass.
> >
> > Bug: skia:9283
> > Change-Id: Ic61d589b2a9c9c2da1c18f3b8ea4480eccc57725
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/688096
> > Commit-Queue: Michael Ludwig <michaelludwig@google.com>
> > Reviewed-by: Robert Phillips <robertphillips@google.com>
>
> Bug: skia:9283
> Change-Id: I5adc49d34c75cd06a100169788aea38b05e72e40
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/692636
> Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
> Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
> Auto-Submit: Michael Ludwig <michaelludwig@google.com>

Bug: skia:9283
Change-Id: I49be8eb2caf961263fcc8b02389c9c6de44dd6f3
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/693058
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
diff --git a/src/effects/imagefilters/SkColorFilterImageFilter.cpp b/src/effects/imagefilters/SkColorFilterImageFilter.cpp
index 1b8fdf6..1cc4f06 100644
--- a/src/effects/imagefilters/SkColorFilterImageFilter.cpp
+++ b/src/effects/imagefilters/SkColorFilterImageFilter.cpp
@@ -5,29 +5,35 @@
  * found in the LICENSE file.
  */
 
-#include "include/core/SkBlendMode.h"
-#include "include/core/SkCanvas.h"
-#include "include/core/SkColor.h"
 #include "include/core/SkColorFilter.h"
 #include "include/core/SkFlattenable.h"
 #include "include/core/SkImageFilter.h"
-#include "include/core/SkPaint.h"
-#include "include/core/SkPoint.h"
 #include "include/core/SkRect.h"
 #include "include/core/SkRefCnt.h"
-#include "include/core/SkSamplingOptions.h"
-#include "include/core/SkScalar.h"
 #include "include/core/SkTypes.h"
 #include "include/effects/SkImageFilters.h"
 #include "src/core/SkColorFilterBase.h"
+#include "src/core/SkImageFilterTypes.h"
 #include "src/core/SkImageFilter_Base.h"
 #include "src/core/SkReadBuffer.h"
-#include "src/core/SkSpecialImage.h"
-#include "src/core/SkSpecialSurface.h"
+#include "src/core/SkRectPriv.h"
 #include "src/core/SkWriteBuffer.h"
+#include "src/effects/imagefilters/SkCropImageFilter.h"
 
 #include <utility>
 
+#if defined(SK_USE_LEGACY_COLORFILTER_IMAGEFILTER)
+
+#include "include/core/SkBlendMode.h"
+#include "include/core/SkCanvas.h"
+#include "include/core/SkColor.h"
+#include "include/core/SkPaint.h"
+#include "include/core/SkPoint.h"
+#include "include/core/SkSamplingOptions.h"
+#include "include/core/SkScalar.h"
+#include "src/core/SkSpecialImage.h"
+#include "src/core/SkSpecialSurface.h"
+
 namespace {
 
 class SkColorFilterImageFilter final : public SkImageFilter_Base {
@@ -178,3 +184,137 @@
 bool SkColorFilterImageFilter::onAffectsTransparentBlack() const {
     return as_CFB(fColorFilter)->affectsTransparentBlack();
 }
+
+#else
+
+namespace {
+
+class SkColorFilterImageFilter final : public SkImageFilter_Base {
+public:
+    SkColorFilterImageFilter(sk_sp<SkColorFilter> cf, sk_sp<SkImageFilter> input)
+            : SkImageFilter_Base(&input, 1, nullptr)
+            , fColorFilter(std::move(cf)) {}
+
+    SkRect computeFastBounds(const SkRect& bounds) const override;
+
+protected:
+    void flatten(SkWriteBuffer&) const override;
+
+private:
+    friend void ::SkRegisterColorFilterImageFilterFlattenable();
+    SK_FLATTENABLE_HOOKS(SkColorFilterImageFilter)
+
+    skif::FilterResult onFilterImage(const skif::Context&) const override;
+
+    skif::LayerSpace<SkIRect> onGetInputLayerBounds(
+            const skif::Mapping& mapping,
+            const skif::LayerSpace<SkIRect>& desiredOutput,
+            const skif::LayerSpace<SkIRect>& contentBounds,
+            VisitChildren recurse) const override;
+
+    skif::LayerSpace<SkIRect> onGetOutputLayerBounds(
+            const skif::Mapping& mapping,
+            const skif::LayerSpace<SkIRect>& contentBounds) const override;
+
+    MatrixCapability onGetCTMCapability() const override { return MatrixCapability::kComplex; }
+
+    bool onAffectsTransparentBlack() const override {
+        return as_CFB(fColorFilter)->affectsTransparentBlack();
+    }
+
+    bool onIsColorFilterNode(SkColorFilter** filter) const override {
+        SkASSERT(1 == this->countInputs());
+        if (filter) {
+            *filter = SkRef(fColorFilter.get());
+        }
+        return true;
+    }
+
+    sk_sp<SkColorFilter> fColorFilter;
+};
+
+} // end namespace
+
+sk_sp<SkImageFilter> SkImageFilters::ColorFilter(sk_sp<SkColorFilter> cf,
+                                                 sk_sp<SkImageFilter> input,
+                                                 const CropRect& cropRect) {
+    if (cf) {
+        SkColorFilter* inputCF;
+        // This is an optimization, as it collapses the hierarchy by just combining the two
+        // colorfilters into a single one, which the new imagefilter will wrap.
+        // NOTE: FilterResults are capable of composing non-adjacent CF nodes together. We could
+        // remove this optimization at construction time, but may as well do the work just once.
+        if (input && input->isColorFilterNode(&inputCF)) {
+            cf = cf->makeComposed(sk_sp<SkColorFilter>(inputCF));
+            input = sk_ref_sp(input->getInput(0));
+        }
+    }
+
+    sk_sp<SkImageFilter> filter = std::move(input);
+    if (cf) {
+        filter = sk_sp<SkImageFilter>(
+                new SkColorFilterImageFilter(std::move(cf), std::move(filter)));
+    }
+    if (cropRect) {
+        filter = SkMakeCropImageFilter(*cropRect, std::move(filter));
+    }
+    return filter;
+}
+
+void SkRegisterColorFilterImageFilterFlattenable() {
+    SK_REGISTER_FLATTENABLE(SkColorFilterImageFilter);
+    // TODO (michaelludwig) - Remove after grace period for SKPs to stop using old name
+    SkFlattenable::Register("SkColorFilterImageFilterImpl", SkColorFilterImageFilter::CreateProc);
+}
+
+sk_sp<SkFlattenable> SkColorFilterImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
+    sk_sp<SkColorFilter> cf(buffer.readColorFilter());
+    return SkImageFilters::ColorFilter(std::move(cf), common.getInput(0), common.cropRect());
+}
+
+void SkColorFilterImageFilter::flatten(SkWriteBuffer& buffer) const {
+    this->SkImageFilter_Base::flatten(buffer);
+    buffer.writeFlattenable(fColorFilter.get());
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+skif::FilterResult SkColorFilterImageFilter::onFilterImage(const Context& ctx) const {
+    skif::FilterResult childOutput = this->filterInput(0, ctx);
+    return childOutput.applyColorFilter(ctx, fColorFilter);
+}
+
+skif::LayerSpace<SkIRect> SkColorFilterImageFilter::onGetInputLayerBounds(
+        const skif::Mapping& mapping,
+        const skif::LayerSpace<SkIRect>& desiredOutput,
+        const skif::LayerSpace<SkIRect>& contentBounds,
+        VisitChildren recurse) const {
+    if (recurse == VisitChildren::kNo) {
+        return desiredOutput;
+    } else {
+        return this->visitInputLayerBounds(mapping, desiredOutput, contentBounds);
+    }
+}
+
+skif::LayerSpace<SkIRect> SkColorFilterImageFilter::onGetOutputLayerBounds(
+        const skif::Mapping& mapping,
+        const skif::LayerSpace<SkIRect>& contentBounds) const {
+    if (this->affectsTransparentBlack()) {
+        return skif::LayerSpace<SkIRect>(SkRectPriv::MakeILarge());
+    } else {
+        return this->visitOutputLayerBounds(mapping, contentBounds);
+    }
+}
+
+SkRect SkColorFilterImageFilter::computeFastBounds(const SkRect& bounds) const {
+    if (this->affectsTransparentBlack()) {
+        return SkRectPriv::MakeLargeS32();
+    } else if (this->getInput(0)) {
+        return this->getInput(0)->computeFastBounds(bounds);
+    } else {
+        return bounds;
+    }
+}
+
+#endif // defined(SK_USE_LEGACY_COLORFILTER_IMAGEFILTER)