Reland "Move runtime shader/colorfilter into SkRuntimeEffect.cpp"

This reverts commit 7281a8623799021d47ebcdb5d0efa6d200cca1cd.

Change-Id: I1759358ede39e2466362cc4d3f0b9530eff08c9e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/271656
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/gn/core.gni b/gn/core.gni
index dff7111..7d59209 100644
--- a/gn/core.gni
+++ b/gn/core.gni
@@ -445,7 +445,6 @@
   "$_src/shaders/SkLights.h",
   "$_src/shaders/SkLocalMatrixShader.cpp",
   "$_src/shaders/SkLocalMatrixShader.h",
-  "$_src/shaders/SkRTShader.cpp",
   "$_src/shaders/SkShader.cpp",
   "$_src/shaders/SkShaderBase.h",
 
diff --git a/include/effects/SkRuntimeEffect.h b/include/effects/SkRuntimeEffect.h
index 921b42e..0840422 100644
--- a/include/effects/SkRuntimeEffect.h
+++ b/include/effects/SkRuntimeEffect.h
@@ -127,6 +127,10 @@
 
     ByteCodeResult toByteCode(const void* inputs);
 
+    static void RegisterFlattenables();
+
+    ~SkRuntimeEffect();
+
 private:
     SkRuntimeEffect(SkString sksl, std::unique_ptr<SkSL::Compiler> compiler,
                     std::unique_ptr<SkSL::Program> baseProgram,
diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp
index 38cd478..9a86a2f 100644
--- a/src/core/SkColorFilter.cpp
+++ b/src/core/SkColorFilter.cpp
@@ -9,7 +9,6 @@
 #include "include/core/SkRefCnt.h"
 #include "include/core/SkString.h"
 #include "include/core/SkUnPreMultiply.h"
-#include "include/effects/SkRuntimeEffect.h"
 #include "include/private/SkNx.h"
 #include "include/private/SkTDArray.h"
 #include "src/core/SkArenaAlloc.h"
@@ -19,7 +18,6 @@
 #include "src/core/SkReadBuffer.h"
 #include "src/core/SkVM.h"
 #include "src/core/SkWriteBuffer.h"
-#include "src/sksl/SkSLInterpreter.h"
 
 #if SK_SUPPORT_GPU
 #include "src/gpu/GrFragmentProcessor.h"
@@ -391,129 +389,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-#include "include/private/SkMutex.h"
-#include "src/sksl/SkSLByteCode.h"
-
-#if SK_SUPPORT_GPU
-#include "include/private/GrRecordingContext.h"
-#include "src/gpu/effects/GrSkSLFP.h"
-#endif
-
-class SkRuntimeColorFilter : public SkColorFilter {
-public:
-    SkRuntimeColorFilter(sk_sp<SkRuntimeEffect> effect, sk_sp<SkData> inputs,
-                         sk_sp<SkColorFilter> children[], size_t childCount)
-            : fEffect(std::move(effect))
-            , fInputs(std::move(inputs))
-            , fChildren(children, children + childCount) {}
-
-#if SK_SUPPORT_GPU
-    std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(
-            GrRecordingContext* context, const GrColorInfo& colorInfo) const override {
-        auto fp = GrSkSLFP::Make(context, fEffect, "Runtime Color Filter", fInputs);
-        for (const auto& child : fChildren) {
-            auto childFP = child ? child->asFragmentProcessor(context, colorInfo) : nullptr;
-            if (!childFP) {
-                // TODO: This is the case that should eventually mean "the original input color"
-                return nullptr;
-            }
-            fp->addChild(std::move(childFP));
-        }
-        return std::move(fp);
-    }
-#endif
-
-    bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const override {
-        auto ctx = rec.fAlloc->make<SkRasterPipeline_InterpreterCtx>();
-        // don't need to set ctx->paintColor
-        ctx->inputs = fInputs->data();
-        ctx->ninputs = fEffect->uniformSize() / 4;
-        ctx->shaderConvention = false;
-
-        SkAutoMutexExclusive ama(fInterpreterMutex);
-        if (!fInterpreter) {
-            auto [byteCode, errorText] = fEffect->toByteCode(fInputs->data());
-            if (!byteCode) {
-                SkDebugf("%s\n", errorText.c_str());
-                return false;
-            }
-            fMain = byteCode->getFunction("main");
-            fInterpreter.reset(
-                           new SkSL::Interpreter<SkRasterPipeline_InterpreterCtx::VECTOR_WIDTH>(
-                                                                          std::move(byteCode)));
-        }
-        ctx->fn = fMain;
-        ctx->interpreter = fInterpreter.get();
-        rec.fPipeline->append(SkRasterPipeline::interpreter, ctx);
-        return true;
-    }
-
-protected:
-    void flatten(SkWriteBuffer& buffer) const override {
-        buffer.writeString(fEffect->source().c_str());
-        if (fInputs) {
-            buffer.writeDataAsByteArray(fInputs.get());
-        } else {
-            buffer.writeByteArray(nullptr, 0);
-        }
-        buffer.write32(fChildren.size());
-        for (const auto& child : fChildren) {
-            buffer.writeFlattenable(child.get());
-        }
-    }
-
-private:
-    SK_FLATTENABLE_HOOKS(SkRuntimeColorFilter)
-
-    sk_sp<SkRuntimeEffect> fEffect;
-    sk_sp<SkData> fInputs;
-    std::vector<sk_sp<SkColorFilter>> fChildren;
-
-    mutable SkMutex fInterpreterMutex;
-    mutable std::unique_ptr<SkSL::Interpreter<SkRasterPipeline_InterpreterCtx::VECTOR_WIDTH>>
-                                                                                       fInterpreter;
-    mutable const SkSL::ByteCodeFunction* fMain;
-
-    friend class SkColorFilter;
-
-    typedef SkColorFilter INHERITED;
-};
-
-sk_sp<SkFlattenable> SkRuntimeColorFilter::CreateProc(SkReadBuffer& buffer) {
-    SkString sksl;
-    buffer.readString(&sksl);
-    sk_sp<SkData> inputs = buffer.readByteArrayAsData();
-
-    auto effect = std::get<0>(SkRuntimeEffect::Make(std::move(sksl)));
-    if (!effect) {
-        buffer.validate(false);
-        return nullptr;
-    }
-
-    size_t childCount = buffer.read32();
-    if (childCount != effect->children().count()) {
-        buffer.validate(false);
-        return nullptr;
-    }
-
-    std::vector<sk_sp<SkColorFilter>> children;
-    children.resize(childCount);
-    for (size_t i = 0; i < children.size(); ++i) {
-        children[i] = buffer.readColorFilter();
-    }
-
-    return effect->makeColorFilter(std::move(inputs), children.data(), children.size());
-}
-
-// Private helper method so SkRuntimeEffect can access SkRuntimeColorFilter
-sk_sp<SkColorFilter> SkMakeRuntimeColorFilter(sk_sp<SkRuntimeEffect> effect, sk_sp<SkData> inputs,
-                                              sk_sp<SkColorFilter> children[], size_t childCount) {
-    return sk_sp<SkColorFilter>(
-            new SkRuntimeColorFilter(std::move(effect), std::move(inputs), children, childCount));
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
 #include "src/core/SkModeColorFilter.h"
 
 void SkColorFilter::RegisterFlattenables() {
@@ -521,5 +396,4 @@
     SK_REGISTER_FLATTENABLE(SkModeColorFilter);
     SK_REGISTER_FLATTENABLE(SkSRGBGammaColorFilter);
     SK_REGISTER_FLATTENABLE(SkMixerColorFilter);
-    SK_REGISTER_FLATTENABLE(SkRuntimeColorFilter);
 }
diff --git a/src/core/SkRuntimeEffect.cpp b/src/core/SkRuntimeEffect.cpp
index 283e540..24640f9 100644
--- a/src/core/SkRuntimeEffect.cpp
+++ b/src/core/SkRuntimeEffect.cpp
@@ -9,11 +9,22 @@
 #include "include/core/SkData.h"
 #include "include/effects/SkRuntimeEffect.h"
 #include "include/private/SkChecksum.h"
-#include "src/shaders/SkRTShader.h"
+#include "include/private/SkMutex.h"
+#include "src/core/SkRasterPipeline.h"
+#include "src/core/SkReadBuffer.h"
+#include "src/core/SkWriteBuffer.h"
 #include "src/sksl/SkSLByteCode.h"
 #include "src/sksl/SkSLCompiler.h"
+#include "src/sksl/SkSLInterpreter.h"
 #include "src/sksl/ir/SkSLVarDeclarations.h"
 
+#if SK_SUPPORT_GPU
+#include "include/private/GrRecordingContext.h"
+#include "src/gpu/GrColorInfo.h"
+#include "src/gpu/GrFPArgs.h"
+#include "src/gpu/effects/GrSkSLFP.h"
+#endif
+
 SkRuntimeEffect::EffectResult SkRuntimeEffect::Make(SkString sksl) {
     auto compiler = std::make_unique<SkSL::Compiler>();
     auto program = compiler->convertProgram(SkSL::Program::kPipelineStage_Kind,
@@ -206,6 +217,8 @@
     SkASSERT(fUniformSize <= this->inputSize());
 }
 
+SkRuntimeEffect::~SkRuntimeEffect() = default;
+
 size_t SkRuntimeEffect::inputSize() const {
     return fInAndUniformVars.empty() ? 0
                                      : SkAlign4(fInAndUniformVars.back().fOffset +
@@ -293,6 +306,257 @@
     return ByteCodeResult(std::move(byteCode), SkString(fCompiler->errorText().c_str()));
 }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+static constexpr int kVectorWidth = SkRasterPipeline_InterpreterCtx::VECTOR_WIDTH;
+
+class SkRuntimeColorFilter : public SkColorFilter {
+public:
+    SkRuntimeColorFilter(sk_sp<SkRuntimeEffect> effect, sk_sp<SkData> inputs,
+                         sk_sp<SkColorFilter> children[], size_t childCount)
+            : fEffect(std::move(effect))
+            , fInputs(std::move(inputs))
+            , fChildren(children, children + childCount) {}
+
+#if SK_SUPPORT_GPU
+    std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(
+            GrRecordingContext* context, const GrColorInfo& colorInfo) const override {
+        auto fp = GrSkSLFP::Make(context, fEffect, "Runtime Color Filter", fInputs);
+        for (const auto& child : fChildren) {
+            auto childFP = child ? child->asFragmentProcessor(context, colorInfo) : nullptr;
+            if (!childFP) {
+                // TODO: This is the case that should eventually mean "the original input color"
+                return nullptr;
+            }
+            fp->addChild(std::move(childFP));
+        }
+        return std::move(fp);
+    }
+#endif
+
+    bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const override {
+        auto ctx = rec.fAlloc->make<SkRasterPipeline_InterpreterCtx>();
+        // don't need to set ctx->paintColor
+        ctx->inputs = fInputs->data();
+        ctx->ninputs = fEffect->uniformSize() / 4;
+        ctx->shaderConvention = false;
+
+        SkAutoMutexExclusive ama(fInterpreterMutex);
+        if (!fInterpreter) {
+            auto [byteCode, errorText] = fEffect->toByteCode(fInputs->data());
+            if (!byteCode) {
+                SkDebugf("%s\n", errorText.c_str());
+                return false;
+            }
+            fMain = byteCode->getFunction("main");
+            fInterpreter.reset(new SkSL::Interpreter<kVectorWidth>(std::move(byteCode)));
+        }
+        ctx->fn = fMain;
+        ctx->interpreter = fInterpreter.get();
+        rec.fPipeline->append(SkRasterPipeline::interpreter, ctx);
+        return true;
+    }
+
+    void flatten(SkWriteBuffer& buffer) const override {
+        buffer.writeString(fEffect->source().c_str());
+        if (fInputs) {
+            buffer.writeDataAsByteArray(fInputs.get());
+        } else {
+            buffer.writeByteArray(nullptr, 0);
+        }
+        buffer.write32(fChildren.size());
+        for (const auto& child : fChildren) {
+            buffer.writeFlattenable(child.get());
+        }
+    }
+
+    SK_FLATTENABLE_HOOKS(SkRuntimeColorFilter)
+
+private:
+    sk_sp<SkRuntimeEffect> fEffect;
+    sk_sp<SkData> fInputs;
+    std::vector<sk_sp<SkColorFilter>> fChildren;
+
+    mutable SkMutex fInterpreterMutex;
+    mutable std::unique_ptr<SkSL::Interpreter<kVectorWidth>> fInterpreter;
+    mutable const SkSL::ByteCodeFunction* fMain;
+};
+
+sk_sp<SkFlattenable> SkRuntimeColorFilter::CreateProc(SkReadBuffer& buffer) {
+    SkString sksl;
+    buffer.readString(&sksl);
+    sk_sp<SkData> inputs = buffer.readByteArrayAsData();
+
+    auto effect = std::get<0>(SkRuntimeEffect::Make(std::move(sksl)));
+    if (!effect) {
+        buffer.validate(false);
+        return nullptr;
+    }
+
+    size_t childCount = buffer.read32();
+    if (childCount != effect->children().count()) {
+        buffer.validate(false);
+        return nullptr;
+    }
+
+    std::vector<sk_sp<SkColorFilter>> children;
+    children.resize(childCount);
+    for (size_t i = 0; i < children.size(); ++i) {
+        children[i] = buffer.readColorFilter();
+    }
+
+    return effect->makeColorFilter(std::move(inputs), children.data(), children.size());
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SkRTShader : public SkShaderBase {
+public:
+    SkRTShader(sk_sp<SkRuntimeEffect> effect, sk_sp<SkData> inputs, const SkMatrix* localMatrix,
+               sk_sp<SkShader>* children, size_t childCount, bool isOpaque)
+            : SkShaderBase(localMatrix)
+            , fEffect(std::move(effect))
+            , fIsOpaque(isOpaque)
+            , fInputs(std::move(inputs))
+            , fChildren(children, children + childCount) {}
+
+    bool isOpaque() const override { return fIsOpaque; }
+
+#if SK_SUPPORT_GPU
+    std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(const GrFPArgs& args) const override {
+        SkMatrix matrix;
+        if (!this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix)->invert(&matrix)) {
+            return nullptr;
+        }
+        auto fp = GrSkSLFP::Make(args.fContext, fEffect, "runtime-shader", fInputs, &matrix);
+        for (const auto& child : fChildren) {
+            auto childFP = child ? as_SB(child)->asFragmentProcessor(args) : nullptr;
+            if (!childFP) {
+                // TODO: This is the case that should eventually mean "the original input color"
+                return nullptr;
+            }
+            fp->addChild(std::move(childFP));
+        }
+        if (GrColorTypeClampType(args.fDstColorInfo->colorType()) != GrClampType::kNone) {
+            return GrFragmentProcessor::ClampPremulOutput(std::move(fp));
+        } else {
+            return std::move(fp);
+        }
+    }
+#endif
+
+    bool onAppendStages(const SkStageRec& rec) const override {
+        SkMatrix inverse;
+        if (!this->computeTotalInverse(rec.fCTM, rec.fLocalM, &inverse)) {
+            return false;
+        }
+
+        auto ctx = rec.fAlloc->make<SkRasterPipeline_InterpreterCtx>();
+        ctx->paintColor = rec.fPaint.getColor4f();
+        ctx->inputs = fInputs->data();
+        ctx->ninputs = fEffect->uniformSize() / 4;
+        ctx->shaderConvention = true;
+
+        SkAutoMutexExclusive ama(fInterpreterMutex);
+        if (!fInterpreter) {
+            auto[byteCode, errorText] = fEffect->toByteCode(fInputs->data());
+            if (!byteCode) {
+                SkDebugf("%s\n", errorText.c_str());
+                return false;
+            }
+            fMain = byteCode->getFunction("main");
+            fInterpreter.reset(new SkSL::Interpreter<kVectorWidth>(std::move(byteCode)));
+        }
+        ctx->fn = fMain;
+        ctx->interpreter = fInterpreter.get();
+
+        rec.fPipeline->append(SkRasterPipeline::seed_shader);
+        rec.fPipeline->append_matrix(rec.fAlloc, inverse);
+        rec.fPipeline->append(SkRasterPipeline::interpreter, ctx);
+        return true;
+    }
+
+    void flatten(SkWriteBuffer& buffer) const override {
+        uint32_t flags = 0;
+        if (fIsOpaque) {
+            flags |= kIsOpaque_Flag;
+        }
+        if (!this->getLocalMatrix().isIdentity()) {
+            flags |= kHasLocalMatrix_Flag;
+        }
+
+        buffer.writeString(fEffect->source().c_str());
+        if (fInputs) {
+            buffer.writeDataAsByteArray(fInputs.get());
+        } else {
+            buffer.writeByteArray(nullptr, 0);
+        }
+        buffer.write32(flags);
+        if (flags & kHasLocalMatrix_Flag) {
+            buffer.writeMatrix(this->getLocalMatrix());
+        }
+        buffer.write32(fChildren.size());
+        for (const auto& child : fChildren) {
+            buffer.writeFlattenable(child.get());
+        }
+    }
+
+    SK_FLATTENABLE_HOOKS(SkRTShader)
+
+private:
+    enum Flags {
+        kIsOpaque_Flag          = 1 << 0,
+        kHasLocalMatrix_Flag    = 1 << 1,
+    };
+
+    sk_sp<SkRuntimeEffect> fEffect;
+    bool fIsOpaque;
+
+    sk_sp<SkData> fInputs;
+    std::vector<sk_sp<SkShader>> fChildren;
+
+    mutable SkMutex fInterpreterMutex;
+    mutable std::unique_ptr<SkSL::Interpreter<kVectorWidth>> fInterpreter;
+    mutable const SkSL::ByteCodeFunction* fMain;
+};
+
+sk_sp<SkFlattenable> SkRTShader::CreateProc(SkReadBuffer& buffer) {
+    SkString sksl;
+    buffer.readString(&sksl);
+    sk_sp<SkData> inputs = buffer.readByteArrayAsData();
+    uint32_t flags = buffer.read32();
+
+    bool isOpaque = SkToBool(flags & kIsOpaque_Flag);
+    SkMatrix localM, *localMPtr = nullptr;
+    if (flags & kHasLocalMatrix_Flag) {
+        buffer.readMatrix(&localM);
+        localMPtr = &localM;
+    }
+
+    auto effect = std::get<0>(SkRuntimeEffect::Make(std::move(sksl)));
+    if (!effect) {
+        buffer.validate(false);
+        return nullptr;
+    }
+
+    size_t childCount = buffer.read32();
+    if (childCount != effect->children().count()) {
+        buffer.validate(false);
+        return nullptr;
+    }
+
+    std::vector<sk_sp<SkShader>> children;
+    children.resize(childCount);
+    for (size_t i = 0; i < children.size(); ++i) {
+        children[i] = buffer.readShader();
+    }
+
+    return effect->makeShader(std::move(inputs), children.data(), children.size(), localMPtr,
+                              isOpaque);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
 sk_sp<SkShader> SkRuntimeEffect::makeShader(sk_sp<SkData> inputs,
                                             sk_sp<SkShader> children[], size_t childCount,
                                             const SkMatrix* localMatrix, bool isOpaque) {
@@ -308,17 +572,22 @@
 sk_sp<SkColorFilter> SkRuntimeEffect::makeColorFilter(sk_sp<SkData> inputs,
                                                       sk_sp<SkColorFilter> children[],
                                                       size_t childCount) {
-    extern sk_sp<SkColorFilter> SkMakeRuntimeColorFilter(sk_sp<SkRuntimeEffect>, sk_sp<SkData>,
-                                                         sk_sp<SkColorFilter>[], size_t);
-
     if (!inputs) {
         inputs = SkData::MakeEmpty();
     }
-    return inputs->size() == this->inputSize() && childCount == fChildren.size()
-        ? SkMakeRuntimeColorFilter(sk_ref_sp(this), std::move(inputs), children, childCount)
+    return inputs && inputs->size() == this->inputSize() && childCount == fChildren.size()
+        ? sk_sp<SkColorFilter>(new SkRuntimeColorFilter(sk_ref_sp(this), std::move(inputs),
+                                                        children, childCount))
         : nullptr;
 }
 
 sk_sp<SkColorFilter> SkRuntimeEffect::makeColorFilter(sk_sp<SkData> inputs) {
     return this->makeColorFilter(std::move(inputs), nullptr, 0);
 }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SkRuntimeEffect::RegisterFlattenables() {
+    SK_REGISTER_FLATTENABLE(SkRuntimeColorFilter);
+    SK_REGISTER_FLATTENABLE(SkRTShader);
+}
diff --git a/src/ports/SkGlobalInitialization_default.cpp b/src/ports/SkGlobalInitialization_default.cpp
index 30d41da..7ef7c31 100644
--- a/src/ports/SkGlobalInitialization_default.cpp
+++ b/src/ports/SkGlobalInitialization_default.cpp
@@ -27,6 +27,7 @@
     #include "include/effects/SkLumaColorFilter.h"
     #include "include/effects/SkOverdrawColorFilter.h"
     #include "include/effects/SkPerlinNoiseShader.h"
+    #include "include/effects/SkRuntimeEffect.h"
     #include "include/effects/SkShaderMaskFilter.h"
     #include "include/effects/SkTableColorFilter.h"
     #include "src/core/SkColorFilter_Matrix.h"
@@ -45,7 +46,6 @@
     #include "src/shaders/SkLightingShader.h"
     #include "src/shaders/SkLocalMatrixShader.h"
     #include "src/shaders/SkPictureShader.h"
-    #include "src/shaders/SkRTShader.h"
     #include "src/shaders/SkShaderBase.h"
 
     #include "include/effects/SkImageFilters.h"
@@ -70,7 +70,6 @@
         SK_REGISTER_FLATTENABLE(SkEmptyShader);
         SK_REGISTER_FLATTENABLE(SkLocalMatrixShader);
         SK_REGISTER_FLATTENABLE(SkPictureShader);
-        SK_REGISTER_FLATTENABLE(SkRTShader);
         SkGradientShader::RegisterFlattenables();
         SkLightingShader::RegisterFlattenables();
         SkPerlinNoiseShader::RegisterFlattenables();
@@ -84,6 +83,9 @@
         SkOverdrawColorFilter::RegisterFlattenables();
         SkTableColorFilter::RegisterFlattenables();
 
+        // Shader & color filter.
+        SkRuntimeEffect::RegisterFlattenables();
+
         // Mask filters.
         SK_REGISTER_FLATTENABLE(SkEmbossMaskFilter);
         SkMaskFilter::RegisterFlattenables();
diff --git a/src/shaders/SkRTShader.cpp b/src/shaders/SkRTShader.cpp
deleted file mode 100644
index f966cc7..0000000
--- a/src/shaders/SkRTShader.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright 2019 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "include/core/SkData.h"
-#include "include/effects/SkRuntimeEffect.h"
-#include "src/core/SkArenaAlloc.h"
-#include "src/core/SkRasterPipeline.h"
-#include "src/core/SkReadBuffer.h"
-#include "src/core/SkWriteBuffer.h"
-#include "src/shaders/SkRTShader.h"
-
-#include "src/sksl/SkSLByteCode.h"
-#include "src/sksl/SkSLCompiler.h"
-#include "src/sksl/SkSLInterpreter.h"
-
-#if SK_SUPPORT_GPU
-#include "src/gpu/GrColorInfo.h"
-#include "src/gpu/GrFPArgs.h"
-#include "src/gpu/effects/GrSkSLFP.h"
-#endif
-
-SkRTShader::SkRTShader(sk_sp<SkRuntimeEffect> effect, sk_sp<SkData> inputs,
-                       const SkMatrix* localMatrix, sk_sp<SkShader>* children, size_t childCount,
-                       bool isOpaque)
-        : SkShaderBase(localMatrix)
-        , fEffect(std::move(effect))
-        , fIsOpaque(isOpaque)
-        , fInputs(std::move(inputs))
-        , fChildren(children, children + childCount) {
-}
-
-SkRTShader::~SkRTShader() = default;
-
-bool SkRTShader::onAppendStages(const SkStageRec& rec) const {
-    SkMatrix inverse;
-    if (!this->computeTotalInverse(rec.fCTM, rec.fLocalM, &inverse)) {
-        return false;
-    }
-
-    auto ctx = rec.fAlloc->make<SkRasterPipeline_InterpreterCtx>();
-    ctx->paintColor = rec.fPaint.getColor4f();
-    ctx->inputs = fInputs->data();
-    ctx->ninputs = fEffect->uniformSize() / 4;
-    ctx->shaderConvention = true;
-
-    SkAutoMutexExclusive ama(fInterpreterMutex);
-    if (!fInterpreter) {
-        auto [byteCode, errorText] = fEffect->toByteCode(fInputs->data());
-        if (!byteCode) {
-            SkDebugf("%s\n", errorText.c_str());
-            return false;
-        }
-        fMain = byteCode->getFunction("main");
-        fInterpreter.reset(new SkSL::Interpreter<SkRasterPipeline_InterpreterCtx::VECTOR_WIDTH>(
-                                                                      std::move(byteCode)));
-    }
-    ctx->fn = fMain;
-    ctx->interpreter = fInterpreter.get();
-
-    rec.fPipeline->append(SkRasterPipeline::seed_shader);
-    rec.fPipeline->append_matrix(rec.fAlloc, inverse);
-    rec.fPipeline->append(SkRasterPipeline::interpreter, ctx);
-    return true;
-}
-
-enum Flags {
-    kIsOpaque_Flag          = 1 << 0,
-    kHasLocalMatrix_Flag    = 1 << 1,
-};
-
-void SkRTShader::flatten(SkWriteBuffer& buffer) const {
-    uint32_t flags = 0;
-    if (fIsOpaque) {
-        flags |= kIsOpaque_Flag;
-    }
-    if (!this->getLocalMatrix().isIdentity()) {
-        flags |= kHasLocalMatrix_Flag;
-    }
-
-    buffer.writeString(fEffect->source().c_str());
-    if (fInputs) {
-        buffer.writeDataAsByteArray(fInputs.get());
-    } else {
-        buffer.writeByteArray(nullptr, 0);
-    }
-    buffer.write32(flags);
-    if (flags & kHasLocalMatrix_Flag) {
-        buffer.writeMatrix(this->getLocalMatrix());
-    }
-    buffer.write32(fChildren.size());
-    for (const auto& child : fChildren) {
-        buffer.writeFlattenable(child.get());
-    }
-}
-
-sk_sp<SkFlattenable> SkRTShader::CreateProc(SkReadBuffer& buffer) {
-    SkString sksl;
-    buffer.readString(&sksl);
-    sk_sp<SkData> inputs = buffer.readByteArrayAsData();
-    uint32_t flags = buffer.read32();
-
-    bool isOpaque = SkToBool(flags & kIsOpaque_Flag);
-    SkMatrix localM, *localMPtr = nullptr;
-    if (flags & kHasLocalMatrix_Flag) {
-        buffer.readMatrix(&localM);
-        localMPtr = &localM;
-    }
-
-    auto effect = std::get<0>(SkRuntimeEffect::Make(std::move(sksl)));
-    if (!effect) {
-        buffer.validate(false);
-        return nullptr;
-    }
-
-    size_t childCount = buffer.read32();
-    if (childCount != effect->children().count()) {
-        buffer.validate(false);
-        return nullptr;
-    }
-
-    std::vector<sk_sp<SkShader>> children;
-    children.resize(childCount);
-    for (size_t i = 0; i < children.size(); ++i) {
-        children[i] = buffer.readShader();
-    }
-
-    return effect->makeShader(std::move(inputs), children.data(), children.size(), localMPtr,
-                              isOpaque);
-}
-
-#if SK_SUPPORT_GPU
-std::unique_ptr<GrFragmentProcessor> SkRTShader::asFragmentProcessor(const GrFPArgs& args) const {
-    SkMatrix matrix;
-    if (!this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix)->invert(&matrix)) {
-        return nullptr;
-    }
-    auto fp = GrSkSLFP::Make(args.fContext, fEffect, "runtime-shader", fInputs, &matrix);
-    for (const auto& child : fChildren) {
-        auto childFP = child ? as_SB(child)->asFragmentProcessor(args) : nullptr;
-        if (!childFP) {
-            // TODO: This is the case that should eventually mean "the original input color"
-            return nullptr;
-        }
-        fp->addChild(std::move(childFP));
-    }
-    if (GrColorTypeClampType(args.fDstColorInfo->colorType()) != GrClampType::kNone) {
-        return GrFragmentProcessor::ClampPremulOutput(std::move(fp));
-    } else {
-        return std::move(fp);
-    }
-}
-#endif
diff --git a/src/shaders/SkRTShader.h b/src/shaders/SkRTShader.h
deleted file mode 100644
index 1ac56ec..0000000
--- a/src/shaders/SkRTShader.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2019 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkRTShader_DEFINED
-#define SkRTShader_DEFINED
-
-#include "include/core/SkString.h"
-#include "include/private/SkMutex.h"
-#include "src/shaders/SkShaderBase.h"
-
-struct GrFPArgs;
-class GrFragmentProcessor;
-class SkData;
-class SkMatrix;
-class SkRuntimeEffect;
-
-namespace SkSL {
-    class ByteCodeFunction;
-
-    template<int width>
-    class Interpreter;
-}
-
-class SkRTShader : public SkShaderBase {
-public:
-    SkRTShader(sk_sp<SkRuntimeEffect> effect, sk_sp<SkData> inputs, const SkMatrix* localMatrix,
-               sk_sp<SkShader>* children, size_t childCount, bool isOpaque);
-    ~SkRTShader() override;
-
-    bool isOpaque() const override { return fIsOpaque; }
-
-#if SK_SUPPORT_GPU
-    std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(const GrFPArgs&) const override;
-#endif
-
-protected:
-    void flatten(SkWriteBuffer&) const override;
-    bool onAppendStages(const SkStageRec& rec) const override;
-
-private:
-    static constexpr int VECTOR_WIDTH = 8;
-
-    SK_FLATTENABLE_HOOKS(SkRTShader)
-
-    sk_sp<SkRuntimeEffect> fEffect;
-    bool fIsOpaque;
-
-    sk_sp<SkData> fInputs;
-    std::vector<sk_sp<SkShader>> fChildren;
-
-    mutable SkMutex fInterpreterMutex;
-    mutable std::unique_ptr<SkSL::Interpreter<VECTOR_WIDTH>> fInterpreter;
-    mutable const SkSL::ByteCodeFunction* fMain;
-
-    typedef SkShaderBase INHERITED;
-};
-
-#endif