Revert "split working-format filter into two parts"

This reverts commit 5db699af9de805037701b959a1f064fdae378211.

Reason for revert: the wrapped color filter now no longer is told that it's in the working format... its asFragmentProcessor() / program() calls will be fed the destination surface's format instead of the working format.

Original change's description:
> split working-format filter into two parts
>
> The old filter represented the whole (xform -> child -> xform) sandwich,
> where this new one represents just one xform, with the factory now using
> Compose() to piece the sandwich together.
>
> This is conceptually simpler, which is nice, and we should also be able
> to use this to replace SkSRGBGammaColorFilter (next CL).
>
> Cq-Include-Trybots: luci.chromium.try:linux-blink-rel
> Change-Id: I6dee3c968329ab74f24e01fcdb82872141cdd496
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/371456
> Reviewed-by: Mike Reed <reed@google.com>
> Commit-Queue: Mike Klein <mtklein@google.com>

TBR=mtklein@google.com,reed@google.com

Change-Id: I2c0daa03dde396a5b2414a8cfe8d3754d6bf6e0c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Cq-Include-Trybots: luci.chromium.try:linux-blink-rel
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/372076
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp
index 03b9389..e1bbb0e 100644
--- a/src/core/SkColorFilter.cpp
+++ b/src/core/SkColorFilter.cpp
@@ -312,102 +312,113 @@
     return MakeSRGBGammaCF<SkSRGBGammaColorFilter::Direction::kSRGBToLinear>();
 }
 
-// This filter assumes its inputs are in Format A and transforms them to format B,
-// pulling each Format property from either custom parameters or the destination surface.
-struct SkColorXformColorFilter : public SkColorFilterBase {
-    struct Format {
-        skcms_TransferFunction tf;     bool useDstTF    = true;
-        skcms_Matrix3x3        gamut;  bool useDstGamut = true;
-        SkAlphaType            at;     bool useDstAT    = true;
-    } fA,fB;
+struct SkWorkingFormatColorFilter : public SkColorFilterBase {
+    sk_sp<SkColorFilter>   fChild;
+    skcms_TransferFunction fTF;     bool fUseDstTF    = true;
+    skcms_Matrix3x3        fGamut;  bool fUseDstGamut = true;
+    SkAlphaType            fAT;     bool fUseDstAT    = true;
 
-    SkColorXformColorFilter(Format A, Format B) : fA(A), fB(B) {}
+    SkWorkingFormatColorFilter(sk_sp<SkColorFilter>          child,
+                               const skcms_TransferFunction* tf,
+                               const skcms_Matrix3x3*        gamut,
+                               const SkAlphaType*            at) {
+        fChild = std::move(child);
+        if (tf)    { fTF    = *tf;    fUseDstTF    = false; }
+        if (gamut) { fGamut = *gamut; fUseDstGamut = false; }
+        if (at)    { fAT    = *at;    fUseDstAT    = false; }
+    }
 
-    static Format Resolve(Format f, SkColorSpace* dstCS, SkAlphaType dstAT) {
-        if (!dstCS) {
-            dstCS = sk_srgb_singleton();
-        }
-        if (f.useDstTF)    { SkAssertResult(dstCS->isNumericalTransferFn(&f.tf)); }
-        if (f.useDstGamut) { SkAssertResult(dstCS->toXYZD50(&f.gamut)); }
-        if (f.useDstAT)    { f.at = dstAT; }
-        return f;
+
+    sk_sp<SkColorSpace> workingFormat(const sk_sp<SkColorSpace>& dstCS, SkAlphaType* at) const {
+        skcms_TransferFunction tf    = fTF;
+        skcms_Matrix3x3        gamut = fGamut;
+
+        if (fUseDstTF   ) { SkAssertResult(dstCS->isNumericalTransferFn(&tf)); }
+        if (fUseDstGamut) { SkAssertResult(dstCS->toXYZD50             (&gamut)); }
+
+        *at = fUseDstAT ? kPremul_SkAlphaType : fAT;
+        return SkColorSpace::MakeRGB(tf, gamut);
     }
 
 #if SK_SUPPORT_GPU
     GrFPResult asFragmentProcessor(std::unique_ptr<GrFragmentProcessor> inputFP,
                                    GrRecordingContext* context,
-                                   const GrColorInfo& dst) const override {
-        const Format A = Resolve(fA, dst.colorSpace(), dst.alphaType()),
-                     B = Resolve(fB, dst.colorSpace(), dst.alphaType());
+                                   const GrColorInfo& dstColorInfo) const override {
+        sk_sp<SkColorSpace> dstCS = dstColorInfo.refColorSpace();
+        if (!dstCS) { dstCS = SkColorSpace::MakeSRGB(); }
 
-        GrColorInfo infoA = {dst.colorType(), A.at, SkColorSpace::MakeRGB(A.tf, A.gamut)},
-                    infoB = {dst.colorType(), B.at, SkColorSpace::MakeRGB(B.tf, B.gamut)};
+        SkAlphaType workingAT;
+        sk_sp<SkColorSpace> workingCS = this->workingFormat(dstCS, &workingAT);
 
-        return GrFPSuccess(GrColorSpaceXformEffect::Make(std::move(inputFP), infoA,infoB));
+        GrColorInfo dst = {dstColorInfo.colorType(), dstColorInfo.alphaType(), dstCS},
+                working = {dstColorInfo.colorType(), workingAT, workingCS};
+
+        auto [ok, fp] = as_CFB(fChild)->asFragmentProcessor(
+                GrColorSpaceXformEffect::Make(std::move(inputFP), dst,working), context, working);
+
+        return ok ? GrFPSuccess(GrColorSpaceXformEffect::Make(std::move(fp), working,dst))
+                  : GrFPFailure(std::move(fp));
     }
 #endif
 
     bool onAppendStages(const SkStageRec&, bool) const override { return false; }
 
-    skvm::Color onProgram(skvm::Builder* p,
-                          skvm::Color c, SkColorSpace* dstCS,
-                          skvm::Uniforms* uniforms, SkArenaAlloc*) const override {
-        const Format A = Resolve(fA, dstCS, kPremul_SkAlphaType),
-                     B = Resolve(fB, dstCS, kPremul_SkAlphaType);
+    skvm::Color onProgram(skvm::Builder* p, skvm::Color c, SkColorSpace* rawDstCS,
+                          skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const override {
+        sk_sp<SkColorSpace> dstCS = sk_ref_sp(rawDstCS);
+        if (!dstCS) { dstCS = SkColorSpace::MakeSRGB(); }
 
-        SkColorInfo infoA = {kUnknown_SkColorType, A.at, SkColorSpace::MakeRGB(A.tf, A.gamut)},
-                    infoB = {kUnknown_SkColorType, B.at, SkColorSpace::MakeRGB(B.tf, B.gamut)};
-        return SkColorSpaceXformSteps{infoA,infoB}.program(p, uniforms, c);
+        SkAlphaType workingAT;
+        sk_sp<SkColorSpace> workingCS = this->workingFormat(dstCS, &workingAT);
+
+        SkColorInfo dst = {kUnknown_SkColorType, kPremul_SkAlphaType, dstCS},
+                working = {kUnknown_SkColorType, workingAT, workingCS};
+
+        c = SkColorSpaceXformSteps{dst,working}.program(p, uniforms, c);
+        c = as_CFB(fChild)->program(p, c, working.colorSpace(), uniforms, alloc);
+        return c ? SkColorSpaceXformSteps{working,dst}.program(p, uniforms, c)
+                 : c;
     }
 
-    uint32_t onGetFlags() const override { return SkColorFilter::kAlphaUnchanged_Flag; }
+    uint32_t onGetFlags() const override { return fChild->getFlags(); }
 
+    SK_FLATTENABLE_HOOKS(SkWorkingFormatColorFilter)
     void flatten(SkWriteBuffer& buffer) const override {
-        auto write_Format = [&](Format f) {
-            buffer.writeBool(f.useDstTF);
-            buffer.writeBool(f.useDstGamut);
-            buffer.writeBool(f.useDstAT);
-            if (!f.useDstTF)    { buffer.writeScalarArray(&f.tf.g, 7); }
-            if (!f.useDstGamut) { buffer.writeScalarArray(&f.gamut.vals[0][0], 9); }
-            if (!f.useDstAT)    { buffer.writeInt(f.at); }
-        };
-        write_Format(fA);
-        write_Format(fB);
+        buffer.writeFlattenable(fChild.get());
+        buffer.writeBool(fUseDstTF);
+        buffer.writeBool(fUseDstGamut);
+        buffer.writeBool(fUseDstAT);
+        if (!fUseDstTF)    { buffer.writeScalarArray(&fTF.g, 7); }
+        if (!fUseDstGamut) { buffer.writeScalarArray(&fGamut.vals[0][0], 9); }
+        if (!fUseDstAT)    { buffer.writeInt(fAT); }
     }
-    SK_FLATTENABLE_HOOKS(SkColorXformColorFilter)
 };
 
-sk_sp<SkFlattenable> SkColorXformColorFilter::CreateProc(SkReadBuffer& buffer) {
-    auto read_Format = [&]() -> Format {
-        Format f;
-        f.useDstTF    = buffer.readBool();
-        f.useDstGamut = buffer.readBool();
-        f.useDstAT    = buffer.readBool();
+sk_sp<SkFlattenable> SkWorkingFormatColorFilter::CreateProc(SkReadBuffer& buffer) {
+    sk_sp<SkColorFilter> child = buffer.readColorFilter();
+    bool useDstTF    = buffer.readBool(),
+         useDstGamut = buffer.readBool(),
+         useDstAT    = buffer.readBool();
 
-        if (!f.useDstTF)    { buffer.readScalarArray(&f.tf.g, 7); }
-        if (!f.useDstGamut) { buffer.readScalarArray(&f.gamut.vals[0][0], 9); }
-        if (!f.useDstAT)    { f.at = buffer.read32LE(kLastEnum_SkAlphaType); }
+    skcms_TransferFunction tf;
+    skcms_Matrix3x3        gamut;
+    SkAlphaType            at;
 
-        return f;
-    };
-    Format A = read_Format(),
-           B = read_Format();
-    return sk_make_sp<SkColorXformColorFilter>(A,B);
+    if (!useDstTF)    { buffer.readScalarArray(&tf.g, 7); }
+    if (!useDstGamut) { buffer.readScalarArray(&gamut.vals[0][0], 9); }
+    if (!useDstAT)    { at = buffer.read32LE(kLastEnum_SkAlphaType); }
+
+    return SkColorFilters::WithWorkingFormat(std::move(child),
+                                             useDstTF    ? nullptr : &tf,
+                                             useDstGamut ? nullptr : &gamut,
+                                             useDstAT    ? nullptr : &at);
 }
 
 sk_sp<SkColorFilter> SkColorFilters::WithWorkingFormat(sk_sp<SkColorFilter>          child,
                                                        const skcms_TransferFunction* tf,
                                                        const skcms_Matrix3x3*        gamut,
                                                        const SkAlphaType*            at) {
-    SkColorXformColorFilter::Format dst, working;
-    if (tf)    { working.tf    = *tf;    working.useDstTF    = false; }
-    if (gamut) { working.gamut = *gamut; working.useDstGamut = false; }
-    if (at)    { working.at    = *at;    working.useDstAT    = false; }
-
-    // input color -> (dst->working) -> child filter -> (working->dst) -> output color
-    return SkColorFilters::Compose(sk_make_sp<SkColorXformColorFilter>(working,dst),
-           SkColorFilters::Compose(child,
-                                   sk_make_sp<SkColorXformColorFilter>(dst,working)));
+    return sk_make_sp<SkWorkingFormatColorFilter>(std::move(child), tf, gamut, at);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -560,5 +571,5 @@
     SK_REGISTER_FLATTENABLE(SkModeColorFilter);
     SK_REGISTER_FLATTENABLE(SkSRGBGammaColorFilter);
     SK_REGISTER_FLATTENABLE(SkMixerColorFilter);
-    SK_REGISTER_FLATTENABLE(SkColorXformColorFilter);
+    SK_REGISTER_FLATTENABLE(SkWorkingFormatColorFilter);
 }