Replace SkShader_Lerp with a runtime shader

Change-Id: If3bd5cfb3fb04c747f913387a6245b35b8d5fc4b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/402398
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/ports/SkGlobalInitialization_default.cpp b/src/ports/SkGlobalInitialization_default.cpp
index e521462..b2f7607 100644
--- a/src/ports/SkGlobalInitialization_default.cpp
+++ b/src/ports/SkGlobalInitialization_default.cpp
@@ -65,7 +65,6 @@
         SK_REGISTER_FLATTENABLE(SkColorFilterShader);
         SK_REGISTER_FLATTENABLE(SkColorShader);
         SK_REGISTER_FLATTENABLE(SkShader_Blend);
-        SK_REGISTER_FLATTENABLE(SkShader_Lerp);
         SK_REGISTER_FLATTENABLE(SkEmptyShader);
         SK_REGISTER_FLATTENABLE(SkLocalMatrixShader);
         SK_REGISTER_FLATTENABLE(SkPictureShader);
diff --git a/src/shaders/SkComposeShader.cpp b/src/shaders/SkComposeShader.cpp
index 873e0c0..8edc0be 100644
--- a/src/shaders/SkComposeShader.cpp
+++ b/src/shaders/SkComposeShader.cpp
@@ -12,6 +12,7 @@
 #include "src/core/SkBlendModePriv.h"
 #include "src/core/SkRasterPipeline.h"
 #include "src/core/SkReadBuffer.h"
+#include "src/core/SkRuntimeEffectPriv.h"
 #include "src/core/SkVM.h"
 #include "src/core/SkWriteBuffer.h"
 #include "src/shaders/SkColorShader.h"
@@ -60,7 +61,22 @@
     if (weight >= 1) {
         return src;
     }
-    return sk_sp<SkShader>(new SkShader_Lerp(weight, std::move(dst), std::move(src)));
+
+    sk_sp<SkRuntimeEffect> effect = SkMakeCachedRuntimeEffect(
+        SkRuntimeEffect::MakeForShader,
+        "uniform shader a;"
+        "uniform shader b;"
+        "uniform half w;"
+        "half4 main(float2 xy) { return mix(sample(a, xy), sample(b, xy), w); }"
+    );
+    SkASSERT(effect);
+
+    sk_sp<SkShader> inputs[] = {dst, src};
+    return effect->makeShader(SkData::MakeWithCopy(&weight, sizeof(weight)),
+                              inputs,
+                              SK_ARRAY_COUNT(inputs),
+                              nullptr,
+                              false);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -150,58 +166,11 @@
     return {};
 }
 
-
-sk_sp<SkFlattenable> SkShader_Lerp::CreateProc(SkReadBuffer& buffer) {
-    sk_sp<SkShader> dst(buffer.readShader());
-    sk_sp<SkShader> src(buffer.readShader());
-    float t = buffer.readScalar();
-    return buffer.isValid() ? SkShaders::Lerp(t, std::move(dst), std::move(src)) : nullptr;
-}
-
-void SkShader_Lerp::flatten(SkWriteBuffer& buffer) const {
-    buffer.writeFlattenable(fDst.get());
-    buffer.writeFlattenable(fSrc.get());
-    buffer.writeScalar(fWeight);
-}
-
-bool SkShader_Lerp::onAppendStages(const SkStageRec& orig_rec) const {
-    const LocalMatrixStageRec rec(orig_rec, this->getLocalMatrix());
-
-    float* res0 = append_two_shaders(rec, fDst.get(), fSrc.get());
-    if (!res0) {
-        return false;
-    }
-
-    rec.fPipeline->append(SkRasterPipeline::load_dst, res0);
-    rec.fPipeline->append(SkRasterPipeline::lerp_1_float, &fWeight);
-    return true;
-}
-
-skvm::Color SkShader_Lerp::onProgram(skvm::Builder* p,
-                                     skvm::Coord device, skvm::Coord local, skvm::Color paint,
-                                     const SkMatrixProvider& mats, const SkMatrix* localM,
-                                     const SkColorInfo& dst,
-                                     skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const {
-    skvm::Color d,s;
-    if ((d = program_or_paint(fDst, p, device,local, paint, mats,localM, dst, uniforms,alloc)) &&
-        (s = program_or_paint(fSrc, p, device,local, paint, mats,localM, dst, uniforms,alloc)))
-    {
-        auto t = p->uniformF(uniforms->pushF(fWeight));
-        return {
-            p->lerp(d.r, s.r, t),
-            p->lerp(d.g, s.g, t),
-            p->lerp(d.b, s.b, t),
-            p->lerp(d.a, s.a, t),
-        };
-    }
-    return {};
-}
-
 #if SK_SUPPORT_GPU
 
 #include "include/gpu/GrRecordingContext.h"
+#include "src/gpu/GrFragmentProcessor.h"
 #include "src/gpu/effects/GrBlendFragmentProcessor.h"
-#include "src/gpu/effects/GrSkSLFP.h"
 
 static std::unique_ptr<GrFragmentProcessor> as_fp(const GrFPArgs& args, SkShader* shader) {
     return shader ? as_SB(shader)->asFragmentProcessor(args) : nullptr;
@@ -214,25 +183,4 @@
     auto fpB = as_fp(args, fSrc.get());
     return GrBlendFragmentProcessor::Make(std::move(fpB), std::move(fpA), fMode);
 }
-
-std::unique_ptr<GrFragmentProcessor> SkShader_Lerp::asFragmentProcessor(
-        const GrFPArgs& orig_args) const {
-    const GrFPArgs::WithPreLocalMatrix args(orig_args, this->getLocalMatrix());
-    auto fpA = as_fp(args, fDst.get());
-    auto fpB = as_fp(args, fSrc.get());
-
-    static constexpr char kCode[] = R"(
-        uniform shader a;
-        uniform shader b;
-        uniform half w;
-
-        half4 main() { return mix(sample(a), sample(b), w); }
-    )";
-
-    auto builder = GrRuntimeFPBuilder::Make<kCode>();
-    builder.uniform("w") = fWeight;
-    builder.child("a") = std::move(fpA);
-    builder.child("b") = std::move(fpB);
-    return builder.makeFP();
-}
 #endif
diff --git a/src/shaders/SkComposeShader.h b/src/shaders/SkComposeShader.h
index 8ceaf38..ee776ba 100644
--- a/src/shaders/SkComposeShader.h
+++ b/src/shaders/SkComposeShader.h
@@ -41,36 +41,4 @@
     using INHERITED = SkShaderBase;
 };
 
-class SkShader_Lerp final : public SkShaderBase {
-public:
-    SkShader_Lerp(float weight, sk_sp<SkShader> dst, sk_sp<SkShader> src)
-        : fDst(std::move(dst))
-        , fSrc(std::move(src))
-        , fWeight(weight)
-    {
-        SkASSERT(weight >= 0 && weight <= 1);
-    }
-
-#if SK_SUPPORT_GPU
-    std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(const GrFPArgs&) const override;
-#endif
-
-protected:
-    SkShader_Lerp(SkReadBuffer&);
-    void flatten(SkWriteBuffer&) const override;
-    bool onAppendStages(const SkStageRec&) const override;
-    skvm::Color onProgram(skvm::Builder*, skvm::Coord device, skvm::Coord local, skvm::Color paint,
-                          const SkMatrixProvider&, const SkMatrix* localM, const SkColorInfo& dst,
-                          skvm::Uniforms*, SkArenaAlloc*) const override;
-
-private:
-    SK_FLATTENABLE_HOOKS(SkShader_Lerp)
-
-    sk_sp<SkShader> fDst;
-    sk_sp<SkShader> fSrc;
-    const float     fWeight;
-
-    using INHERITED = SkShaderBase;
-};
-
 #endif