/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include "src/gpu/GrFragmentProcessor.h"

#include "src/core/SkRuntimeEffectPriv.h"
#include "src/gpu/GrPipeline.h"
#include "src/gpu/GrProcessorAnalysis.h"
#include "src/gpu/GrShaderCaps.h"
#include "src/gpu/effects/GrBlendFragmentProcessor.h"
#include "src/gpu/effects/GrSkSLFP.h"
#include "src/gpu/effects/GrTextureEffect.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"

bool GrFragmentProcessor::isEqual(const GrFragmentProcessor& that) const {
    if (this->classID() != that.classID()) {
        return false;
    }
    if (this->sampleUsage() != that.sampleUsage()) {
        return false;
    }
    if (!this->onIsEqual(that)) {
        return false;
    }
    if (this->numChildProcessors() != that.numChildProcessors()) {
        return false;
    }
    for (int i = 0; i < this->numChildProcessors(); ++i) {
        auto thisChild = this->childProcessor(i),
             thatChild = that .childProcessor(i);
        if (SkToBool(thisChild) != SkToBool(thatChild)) {
            return false;
        }
        if (thisChild && !thisChild->isEqual(*thatChild)) {
            return false;
        }
    }
    return true;
}

void GrFragmentProcessor::visitProxies(const GrVisitProxyFunc& func) const {
    this->visitTextureEffects([&func](const GrTextureEffect& te) {
        func(te.view().proxy(), te.samplerState().mipmapped());
    });
}

void GrFragmentProcessor::visitTextureEffects(
        const std::function<void(const GrTextureEffect&)>& func) const {
    if (auto* te = this->asTextureEffect()) {
        func(*te);
    }
    for (auto& child : fChildProcessors) {
        if (child) {
            child->visitTextureEffects(func);
        }
    }
}

void GrFragmentProcessor::visitWithImpls(
        const std::function<void(const GrFragmentProcessor&, ProgramImpl&)>& f,
        ProgramImpl& impl) const {
    f(*this, impl);
    SkASSERT(impl.numChildProcessors() == this->numChildProcessors());
    for (int i = 0; i < this->numChildProcessors(); ++i) {
        if (const auto* child = this->childProcessor(i)) {
            child->visitWithImpls(f, *impl.childProcessor(i));
        }
    }
}

GrTextureEffect* GrFragmentProcessor::asTextureEffect() {
    if (this->classID() == kGrTextureEffect_ClassID) {
        return static_cast<GrTextureEffect*>(this);
    }
    return nullptr;
}

const GrTextureEffect* GrFragmentProcessor::asTextureEffect() const {
    if (this->classID() == kGrTextureEffect_ClassID) {
        return static_cast<const GrTextureEffect*>(this);
    }
    return nullptr;
}

#if GR_TEST_UTILS
static void recursive_dump_tree_info(const GrFragmentProcessor& fp,
                                     SkString indent,
                                     SkString* text) {
    for (int index = 0; index < fp.numChildProcessors(); ++index) {
        text->appendf("\n%s(#%d) -> ", indent.c_str(), index);
        if (const GrFragmentProcessor* childFP = fp.childProcessor(index)) {
            text->append(childFP->dumpInfo());
            indent.append("\t");
            recursive_dump_tree_info(*childFP, indent, text);
        } else {
            text->append("null");
        }
    }
}

SkString GrFragmentProcessor::dumpTreeInfo() const {
    SkString text = this->dumpInfo();
    recursive_dump_tree_info(*this, SkString("\t"), &text);
    text.append("\n");
    return text;
}
#endif

std::unique_ptr<GrFragmentProcessor::ProgramImpl> GrFragmentProcessor::makeProgramImpl() const {
    std::unique_ptr<ProgramImpl> impl = this->onMakeProgramImpl();
    impl->fChildProcessors.push_back_n(fChildProcessors.count());
    for (int i = 0; i < fChildProcessors.count(); ++i) {
        impl->fChildProcessors[i] = fChildProcessors[i] ? fChildProcessors[i]->makeProgramImpl()
                                                        : nullptr;
    }
    return impl;
}

int GrFragmentProcessor::numNonNullChildProcessors() const {
    return std::count_if(fChildProcessors.begin(), fChildProcessors.end(),
                         [](const auto& c) { return c != nullptr; });
}

#ifdef SK_DEBUG
bool GrFragmentProcessor::isInstantiated() const {
    bool result = true;
    this->visitTextureEffects([&result](const GrTextureEffect& te) {
        if (!te.texture()) {
            result = false;
        }
    });
    return result;
}
#endif

void GrFragmentProcessor::registerChild(std::unique_ptr<GrFragmentProcessor> child,
                                        SkSL::SampleUsage sampleUsage) {
    SkASSERT(sampleUsage.isSampled());

    if (!child) {
        fChildProcessors.push_back(nullptr);
        return;
    }

    // The child should not have been attached to another FP already and not had any sampling
    // strategy set on it.
    SkASSERT(!child->fParent && !child->sampleUsage().isSampled());

    // Configure child's sampling state first
    child->fUsage = sampleUsage;

    // Propagate the "will read dest-color" flag up to parent FPs.
    if (child->willReadDstColor()) {
        this->setWillReadDstColor();
    }

    // If this child receives passthrough or matrix transformed coords from its parent then note
    // that the parent's coords are used indirectly to ensure that they aren't omitted.
    if ((sampleUsage.isPassThrough() || sampleUsage.isUniformMatrix()) &&
        child->usesSampleCoords()) {
        fFlags |= kUsesSampleCoordsIndirectly_Flag;
    }

    // Record that the child is attached to us; this FP is the source of any uniform data needed
    // to evaluate the child sample matrix.
    child->fParent = this;
    fChildProcessors.push_back(std::move(child));

    // Validate: our sample strategy comes from a parent we shouldn't have yet.
    SkASSERT(!fUsage.isSampled() && !fParent);
}

void GrFragmentProcessor::cloneAndRegisterAllChildProcessors(const GrFragmentProcessor& src) {
    for (int i = 0; i < src.numChildProcessors(); ++i) {
        if (auto fp = src.childProcessor(i)) {
            this->registerChild(fp->clone(), fp->sampleUsage());
        } else {
            this->registerChild(nullptr);
        }
    }
}

std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MakeColor(SkPMColor4f color) {
    // Use ColorFilter signature/factory to get the constant output for constant input optimization
    static auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForColorFilter, R"(
        uniform half4 color;
        half4 main(half4 inColor) { return color; }
    )");
    SkASSERT(SkRuntimeEffectPriv::SupportsConstantOutputForConstantInput(effect));
    return GrSkSLFP::Make(effect, "color_fp", /*inputFP=*/nullptr,
                          color.isOpaque() ? GrSkSLFP::OptFlags::kPreservesOpaqueInput
                                           : GrSkSLFP::OptFlags::kNone,
                          "color", color);
}

std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MulChildByInputAlpha(
        std::unique_ptr<GrFragmentProcessor> fp) {
    if (!fp) {
        return nullptr;
    }
    return GrBlendFragmentProcessor::Make(/*src=*/nullptr,
                                          OverrideInput(std::move(fp), SK_PMColor4fWHITE),
                                          SkBlendMode::kDstIn);
}

std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MulInputByChildAlpha(
        std::unique_ptr<GrFragmentProcessor> fp) {
    if (!fp) {
        return nullptr;
    }
    return GrBlendFragmentProcessor::Make(/*src=*/nullptr,
                                          OverrideInput(std::move(fp), SK_PMColor4fWHITE),
                                          SkBlendMode::kSrcIn);
}

std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::ModulateAlpha(
        std::unique_ptr<GrFragmentProcessor> inputFP, const SkPMColor4f& color) {
    auto colorFP = MakeColor(color);
    return GrBlendFragmentProcessor::Make(std::move(colorFP),
                                          std::move(inputFP),
                                          SkBlendMode::kSrcIn);
}

std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::ModulateRGBA(
        std::unique_ptr<GrFragmentProcessor> inputFP, const SkPMColor4f& color) {
    auto colorFP = MakeColor(color);
    return GrBlendFragmentProcessor::Make(std::move(colorFP),
                                          std::move(inputFP),
                                          SkBlendMode::kModulate);
}

std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::ClampOutput(
        std::unique_ptr<GrFragmentProcessor> fp) {
    SkASSERT(fp);
    static auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForColorFilter, R"(
        half4 main(half4 inColor) {
            return saturate(inColor);
        }
    )");
    SkASSERT(SkRuntimeEffectPriv::SupportsConstantOutputForConstantInput(effect));
    return GrSkSLFP::Make(
            effect, "Clamp", std::move(fp), GrSkSLFP::OptFlags::kPreservesOpaqueInput);
}

std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::ClampPremulOutput(
        std::unique_ptr<GrFragmentProcessor> fp) {
    SkASSERT(fp);
    static auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForColorFilter, R"(
        half4 main(half4 inColor) {
            half alpha = saturate(inColor.a);
            return half4(clamp(inColor.rgb, 0, alpha), alpha);
        }
    )");
    SkASSERT(SkRuntimeEffectPriv::SupportsConstantOutputForConstantInput(effect));
    return GrSkSLFP::Make(
            effect, "ClampPremul", std::move(fp), GrSkSLFP::OptFlags::kPreservesOpaqueInput);
}

std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::SwizzleOutput(
        std::unique_ptr<GrFragmentProcessor> fp, const GrSwizzle& swizzle) {
    class SwizzleFragmentProcessor : public GrFragmentProcessor {
    public:
        static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp,
                                                         const GrSwizzle& swizzle) {
            return std::unique_ptr<GrFragmentProcessor>(
                    new SwizzleFragmentProcessor(std::move(fp), swizzle));
        }

        const char* name() const override { return "Swizzle"; }

        std::unique_ptr<GrFragmentProcessor> clone() const override {
            return Make(this->childProcessor(0)->clone(), fSwizzle);
        }

    private:
        SwizzleFragmentProcessor(std::unique_ptr<GrFragmentProcessor> fp, const GrSwizzle& swizzle)
                : INHERITED(kSwizzleFragmentProcessor_ClassID, ProcessorOptimizationFlags(fp.get()))
                , fSwizzle(swizzle) {
            this->registerChild(std::move(fp));
        }

        std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override {
            class Impl : public ProgramImpl {
            public:
                void emitCode(EmitArgs& args) override {
                    SkString childColor = this->invokeChild(0, args);

                    const SwizzleFragmentProcessor& sfp = args.fFp.cast<SwizzleFragmentProcessor>();
                    const GrSwizzle& swizzle = sfp.fSwizzle;
                    GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;

                    fragBuilder->codeAppendf("return %s.%s;",
                                             childColor.c_str(), swizzle.asString().c_str());
                }
            };
            return std::make_unique<Impl>();
        }

        void onAddToKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
            b->add32(fSwizzle.asKey());
        }

        bool onIsEqual(const GrFragmentProcessor& other) const override {
            const SwizzleFragmentProcessor& sfp = other.cast<SwizzleFragmentProcessor>();
            return fSwizzle == sfp.fSwizzle;
        }

        SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
            return fSwizzle.applyTo(ConstantOutputForConstantInput(this->childProcessor(0), input));
        }

        GrSwizzle fSwizzle;

        using INHERITED = GrFragmentProcessor;
    };

    if (!fp) {
        return nullptr;
    }
    if (GrSwizzle::RGBA() == swizzle) {
        return fp;
    }
    return SwizzleFragmentProcessor::Make(std::move(fp), swizzle);
}

std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MakeInputPremulAndMulByOutput(
        std::unique_ptr<GrFragmentProcessor> fp) {
    class PremulFragmentProcessor : public GrFragmentProcessor {
    public:
        static std::unique_ptr<GrFragmentProcessor> Make(
                std::unique_ptr<GrFragmentProcessor> processor) {
            return std::unique_ptr<GrFragmentProcessor>(
                    new PremulFragmentProcessor(std::move(processor)));
        }

        const char* name() const override { return "Premultiply"; }

        std::unique_ptr<GrFragmentProcessor> clone() const override {
            return Make(this->childProcessor(0)->clone());
        }

    private:
        PremulFragmentProcessor(std::unique_ptr<GrFragmentProcessor> processor)
                : INHERITED(kPremulFragmentProcessor_ClassID, OptFlags(processor.get())) {
            this->registerChild(std::move(processor));
        }

        std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override {
            class Impl : public ProgramImpl {
            public:
                void emitCode(EmitArgs& args) override {
                    GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
                    SkString temp = this->invokeChild(/*childIndex=*/0, "half4(1)", args);
                    fragBuilder->codeAppendf("half4 color = %s;", temp.c_str());
                    fragBuilder->codeAppendf("color.rgb *= %s.rgb;", args.fInputColor);
                    fragBuilder->codeAppendf("return color * %s.a;", args.fInputColor);
                }
            };
            return std::make_unique<Impl>();
        }

        void onAddToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}

        bool onIsEqual(const GrFragmentProcessor&) const override { return true; }

        static OptimizationFlags OptFlags(const GrFragmentProcessor* inner) {
            OptimizationFlags flags = kNone_OptimizationFlags;
            if (inner->preservesOpaqueInput()) {
                flags |= kPreservesOpaqueInput_OptimizationFlag;
            }
            if (inner->hasConstantOutputForConstantInput()) {
                flags |= kConstantOutputForConstantInput_OptimizationFlag;
            }
            return flags;
        }

        SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
            SkPMColor4f childColor = ConstantOutputForConstantInput(this->childProcessor(0),
                                                                    SK_PMColor4fWHITE);
            SkPMColor4f premulInput = SkColor4f{ input.fR, input.fG, input.fB, input.fA }.premul();
            return premulInput * childColor;
        }

        using INHERITED = GrFragmentProcessor;
    };
    if (!fp) {
        return nullptr;
    }
    return PremulFragmentProcessor::Make(std::move(fp));
}

//////////////////////////////////////////////////////////////////////////////

std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::OverrideInput(
        std::unique_ptr<GrFragmentProcessor> fp, const SkPMColor4f& color, bool useUniform) {
    if (!fp) {
        return nullptr;
    }
    static auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForColorFilter, R"(
        uniform colorFilter fp;  // Declared as colorFilter so we can pass a color
        uniform half4 color;
        half4 main(half4 inColor) {
            return fp.eval(color);
        }
    )");
    SkASSERT(SkRuntimeEffectPriv::SupportsConstantOutputForConstantInput(effect));
    return GrSkSLFP::Make(effect, "OverrideInput", /*inputFP=*/nullptr,
                          color.isOpaque() ? GrSkSLFP::OptFlags::kPreservesOpaqueInput
                                           : GrSkSLFP::OptFlags::kNone,
                          "fp", std::move(fp),
                          "color", GrSkSLFP::SpecializeIf(!useUniform, color));
}

//////////////////////////////////////////////////////////////////////////////

std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::UseDestColorAsInput(
        std::unique_ptr<GrFragmentProcessor> fp) {
    static auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForBlender, R"(
        uniform colorFilter fp;  // Declared as colorFilter so we can pass a color
        half4 main(half4 src, half4 dst) {
            return fp.eval(dst);
        }
    )");
    return GrSkSLFP::Make(effect, "UseDestColorAsInput", /*inputFP=*/nullptr,
                          GrSkSLFP::OptFlags::kNone, "fp", std::move(fp));
}

//////////////////////////////////////////////////////////////////////////////

std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MakeInputOpaqueAndPostApplyAlpha(
        std::unique_ptr<GrFragmentProcessor> fp) {
    if (!fp) {
        return nullptr;
    }
    static auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForColorFilter, R"(
        uniform colorFilter fp;  // Declared as colorFilter so we can pass a color
        half4 main(half4 inColor) {
            return inColor.a * fp.eval(unpremul(inColor).rgb1);
        }
    )");
    return GrSkSLFP::Make(effect,
                          "MakeInputOpaque",
                          /*inputFP=*/nullptr,
                          GrSkSLFP::OptFlags::kPreservesOpaqueInput,
                          "fp", std::move(fp));
}

//////////////////////////////////////////////////////////////////////////////

std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::Compose(
        std::unique_ptr<GrFragmentProcessor> f, std::unique_ptr<GrFragmentProcessor> g) {
    class ComposeProcessor : public GrFragmentProcessor {
    public:
        static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> f,
                                                         std::unique_ptr<GrFragmentProcessor> g) {
            return std::unique_ptr<GrFragmentProcessor>(new ComposeProcessor(std::move(f),
                                                                             std::move(g)));
        }

        const char* name() const override { return "Compose"; }

        std::unique_ptr<GrFragmentProcessor> clone() const override {
            return std::unique_ptr<GrFragmentProcessor>(new ComposeProcessor(*this));
        }

    private:
        std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override {
            class Impl : public ProgramImpl {
            public:
                void emitCode(EmitArgs& args) override {
                    SkString result = this->invokeChild(1, args);         // g(x)
                    result = this->invokeChild(0, result.c_str(), args);  // f(g(x))
                    args.fFragBuilder->codeAppendf("return %s;", result.c_str());
                }
            };
            return std::make_unique<Impl>();
        }

        ComposeProcessor(std::unique_ptr<GrFragmentProcessor> f,
                         std::unique_ptr<GrFragmentProcessor> g)
                : INHERITED(kSeriesFragmentProcessor_ClassID,
                            f->optimizationFlags() & g->optimizationFlags()) {
            this->registerChild(std::move(f));
            this->registerChild(std::move(g));
        }

        ComposeProcessor(const ComposeProcessor& that) : INHERITED(that) {}

        void onAddToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}

        bool onIsEqual(const GrFragmentProcessor&) const override { return true; }

        SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override {
            SkPMColor4f color = inColor;
            color = ConstantOutputForConstantInput(this->childProcessor(1), color);
            color = ConstantOutputForConstantInput(this->childProcessor(0), color);
            return color;
        }

        using INHERITED = GrFragmentProcessor;
    };

    // Allow either of the composed functions to be null.
    if (f == nullptr) {
        return g;
    }
    if (g == nullptr) {
        return f;
    }

    // Run an optimization pass on this composition.
    GrProcessorAnalysisColor inputColor;
    inputColor.setToUnknown();

    std::unique_ptr<GrFragmentProcessor> series[2] = {std::move(g), std::move(f)};
    GrColorFragmentProcessorAnalysis info(inputColor, series, SK_ARRAY_COUNT(series));

    SkPMColor4f knownColor;
    int leadingFPsToEliminate = info.initialProcessorsToEliminate(&knownColor);
    switch (leadingFPsToEliminate) {
        default:
            // We shouldn't eliminate more than we started with.
            SkASSERT(leadingFPsToEliminate <= 2);
            [[fallthrough]];
        case 0:
            // Compose the two processors as requested.
            return ComposeProcessor::Make(/*f=*/std::move(series[1]), /*g=*/std::move(series[0]));
        case 1:
            // Replace the first processor with a constant color.
            return ComposeProcessor::Make(/*f=*/std::move(series[1]),
                                          /*g=*/MakeColor(knownColor));
        case 2:
            // Replace the entire composition with a constant color.
            return MakeColor(knownColor);
    }
}

//////////////////////////////////////////////////////////////////////////////

std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::ColorMatrix(
        std::unique_ptr<GrFragmentProcessor> child,
        const float matrix[20],
        bool unpremulInput,
        bool clampRGBOutput,
        bool premulOutput) {
    static auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForColorFilter, R"(
        uniform half4x4 m;
        uniform half4   v;
        uniform int unpremulInput;   // always specialized
        uniform int clampRGBOutput;  // always specialized
        uniform int premulOutput;    // always specialized
        half4 main(half4 color) {
            if (bool(unpremulInput)) {
                color = unpremul(color);
            }
            color = m * color + v;
            if (bool(clampRGBOutput)) {
                color = saturate(color);
            } else {
                color.a = saturate(color.a);
            }
            if (bool(premulOutput)) {
                color.rgb *= color.a;
            }
            return color;
        }
    )");
    SkASSERT(SkRuntimeEffectPriv::SupportsConstantOutputForConstantInput(effect));

    SkM44 m44(matrix[ 0], matrix[ 1], matrix[ 2], matrix[ 3],
              matrix[ 5], matrix[ 6], matrix[ 7], matrix[ 8],
              matrix[10], matrix[11], matrix[12], matrix[13],
              matrix[15], matrix[16], matrix[17], matrix[18]);
    SkV4 v4 = {matrix[4], matrix[9], matrix[14], matrix[19]};
    return GrSkSLFP::Make(effect, "ColorMatrix", std::move(child), GrSkSLFP::OptFlags::kNone,
                          "m", m44,
                          "v", v4,
                          "unpremulInput",  GrSkSLFP::Specialize(unpremulInput  ? 1 : 0),
                          "clampRGBOutput", GrSkSLFP::Specialize(clampRGBOutput ? 1 : 0),
                          "premulOutput",   GrSkSLFP::Specialize(premulOutput   ? 1 : 0));
}

//////////////////////////////////////////////////////////////////////////////

std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::SurfaceColor() {
    class SurfaceColorProcessor : public GrFragmentProcessor {
    public:
        static std::unique_ptr<GrFragmentProcessor> Make() {
            return std::unique_ptr<GrFragmentProcessor>(new SurfaceColorProcessor());
        }

        std::unique_ptr<GrFragmentProcessor> clone() const override { return Make(); }

        const char* name() const override { return "SurfaceColor"; }

    private:
        std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override {
            class Impl : public ProgramImpl {
            public:
                void emitCode(EmitArgs& args) override {
                    const char* dstColor = args.fFragBuilder->dstColor();
                    args.fFragBuilder->codeAppendf("return %s;", dstColor);
                }
            };
            return std::make_unique<Impl>();
        }

        SurfaceColorProcessor()
                : INHERITED(kSurfaceColorProcessor_ClassID, kNone_OptimizationFlags) {
            this->setWillReadDstColor();
        }

        void onAddToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}

        bool onIsEqual(const GrFragmentProcessor&) const override { return true; }

        using INHERITED = GrFragmentProcessor;
    };

    return SurfaceColorProcessor::Make();
}

//////////////////////////////////////////////////////////////////////////////

std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::DeviceSpace(
        std::unique_ptr<GrFragmentProcessor> fp) {
    if (!fp) {
        return nullptr;
    }

    class DeviceSpace : GrFragmentProcessor {
    public:
        static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp) {
            return std::unique_ptr<GrFragmentProcessor>(new DeviceSpace(std::move(fp)));
        }

    private:
        DeviceSpace(std::unique_ptr<GrFragmentProcessor> fp)
                : GrFragmentProcessor(kDeviceSpace_ClassID, fp->optimizationFlags()) {
            // Passing FragCoord here is the reason this is a subclass and not a runtime-FP.
            this->registerChild(std::move(fp), SkSL::SampleUsage::FragCoord());
        }

        std::unique_ptr<GrFragmentProcessor> clone() const override {
            auto child = this->childProcessor(0)->clone();
            return std::unique_ptr<GrFragmentProcessor>(new DeviceSpace(std::move(child)));
        }

        SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& f) const override {
            return this->childProcessor(0)->constantOutputForConstantInput(f);
        }

        std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override {
            class Impl : public ProgramImpl {
            public:
                Impl() = default;
                void emitCode(ProgramImpl::EmitArgs& args) override {
                    auto child = this->invokeChild(0, args.fInputColor, args, "sk_FragCoord.xy");
                    args.fFragBuilder->codeAppendf("return %s;", child.c_str());
                }
            };
            return std::make_unique<Impl>();
        }

        void onAddToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}

        bool onIsEqual(const GrFragmentProcessor& processor) const override { return true; }

        const char* name() const override { return "DeviceSpace"; }
    };

    return DeviceSpace::Make(std::move(fp));
}

//////////////////////////////////////////////////////////////////////////////

#define CLIP_EDGE_SKSL              \
    "const int kFillBW = 0;"        \
    "const int kFillAA = 1;"        \
    "const int kInverseFillBW = 2;" \
    "const int kInverseFillAA = 3;"

static_assert(static_cast<int>(GrClipEdgeType::kFillBW) == 0);
static_assert(static_cast<int>(GrClipEdgeType::kFillAA) == 1);
static_assert(static_cast<int>(GrClipEdgeType::kInverseFillBW) == 2);
static_assert(static_cast<int>(GrClipEdgeType::kInverseFillAA) == 3);

std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::Rect(
        std::unique_ptr<GrFragmentProcessor> inputFP, GrClipEdgeType edgeType, SkRect rect) {
    static auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForShader, CLIP_EDGE_SKSL R"(
        uniform int edgeType;  // GrClipEdgeType, specialized
        uniform float4 rectUniform;

        half4 main(float2 xy, half4 inColor) {
            half coverage;
            if (edgeType == kFillBW || edgeType == kInverseFillBW) {
                // non-AA
                coverage = all(greaterThan(float4(sk_FragCoord.xy, rectUniform.zw),
                                           float4(rectUniform.xy, sk_FragCoord.xy))) ? 1 : 0;
            } else {
                // compute coverage relative to left and right edges, add, then subtract 1 to
                // account for double counting. And similar for top/bottom.
                half4 dists4 = clamp(half4(1, 1, -1, -1) *
                                     half4(sk_FragCoord.xyxy - rectUniform), 0, 1);
                half2 dists2 = dists4.xy + dists4.zw - 1;
                coverage = dists2.x * dists2.y;
            }

            if (edgeType == kInverseFillBW || edgeType == kInverseFillAA) {
                coverage = 1.0 - coverage;
            }

            return inColor * coverage;
        }
    )");

    SkASSERT(rect.isSorted());
    // The AA math in the shader evaluates to 0 at the uploaded coordinates, so outset by 0.5
    // to interpolate from 0 at a half pixel inset and 1 at a half pixel outset of rect.
    SkRect rectUniform = GrClipEdgeTypeIsAA(edgeType) ? rect.makeOutset(.5f, .5f) : rect;

    return GrSkSLFP::Make(effect, "Rect", std::move(inputFP),
                          GrSkSLFP::OptFlags::kCompatibleWithCoverageAsAlpha,
                          "edgeType", GrSkSLFP::Specialize(static_cast<int>(edgeType)),
                          "rectUniform", rectUniform);
}

GrFPResult GrFragmentProcessor::Circle(std::unique_ptr<GrFragmentProcessor> inputFP,
                                       GrClipEdgeType edgeType,
                                       SkPoint center,
                                       float radius) {
    // A radius below half causes the implicit insetting done by this processor to become
    // inverted. We could handle this case by making the processor code more complicated.
    if (radius < .5f && GrClipEdgeTypeIsInverseFill(edgeType)) {
        return GrFPFailure(std::move(inputFP));
    }

    static auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForShader, CLIP_EDGE_SKSL R"(
        uniform int edgeType;  // GrClipEdgeType, specialized
        // The circle uniform is (center.x, center.y, radius + 0.5, 1 / (radius + 0.5)) for regular
        // fills and (..., radius - 0.5, 1 / (radius - 0.5)) for inverse fills.
        uniform float4 circle;

        half4 main(float2 xy, half4 inColor) {
            // TODO: Right now the distance to circle calculation is performed in a space normalized
            // to the radius and then denormalized. This is to mitigate overflow on devices that
            // don't have full float.
            half d;
            if (edgeType == kInverseFillBW || edgeType == kInverseFillAA) {
                d = half((length((circle.xy - sk_FragCoord.xy) * circle.w) - 1.0) * circle.z);
            } else {
                d = half((1.0 - length((circle.xy - sk_FragCoord.xy) *  circle.w)) * circle.z);
            }
            if (edgeType == kFillAA || edgeType == kInverseFillAA) {
                return inColor * saturate(d);
            } else {
                return d > 0.5 ? inColor : half4(0);
            }
        }
    )");

    SkScalar effectiveRadius = radius;
    if (GrClipEdgeTypeIsInverseFill(edgeType)) {
        effectiveRadius -= 0.5f;
        // When the radius is 0.5 effectiveRadius is 0 which causes an inf * 0 in the shader.
        effectiveRadius = std::max(0.001f, effectiveRadius);
    } else {
        effectiveRadius += 0.5f;
    }
    SkV4 circle = {center.fX, center.fY, effectiveRadius, SkScalarInvert(effectiveRadius)};

    return GrFPSuccess(GrSkSLFP::Make(effect, "Circle", std::move(inputFP),
                                      GrSkSLFP::OptFlags::kCompatibleWithCoverageAsAlpha,
                                      "edgeType", GrSkSLFP::Specialize(static_cast<int>(edgeType)),
                                      "circle", circle));
}

GrFPResult GrFragmentProcessor::Ellipse(std::unique_ptr<GrFragmentProcessor> inputFP,
                                        GrClipEdgeType edgeType,
                                        SkPoint center,
                                        SkPoint radii,
                                        const GrShaderCaps& caps) {
    const bool medPrecision = !caps.floatIs32Bits();

    // Small radii produce bad results on devices without full float.
    if (medPrecision && (radii.fX < 0.5f || radii.fY < 0.5f)) {
        return GrFPFailure(std::move(inputFP));
    }
    // Very narrow ellipses produce bad results on devices without full float
    if (medPrecision && (radii.fX > 255*radii.fY || radii.fY > 255*radii.fX)) {
        return GrFPFailure(std::move(inputFP));
    }
    // Very large ellipses produce bad results on devices without full float
    if (medPrecision && (radii.fX > 16384 || radii.fY > 16384)) {
        return GrFPFailure(std::move(inputFP));
    }

    static auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForShader, CLIP_EDGE_SKSL R"(
        uniform int edgeType;      // GrClipEdgeType, specialized
        uniform int medPrecision;  // !sk_Caps.floatIs32Bits, specialized

        uniform float4 ellipse;
        uniform float2 scale;    // only for medPrecision

        half4 main(float2 xy, half4 inColor) {
            // d is the offset to the ellipse center
            float2 d = sk_FragCoord.xy - ellipse.xy;
            // If we're on a device with a "real" mediump then we'll do the distance computation in
            // a space that is normalized by the larger radius or 128, whichever is smaller. The
            // scale uniform will be scale, 1/scale. The inverse squared radii uniform values are
            // already in this normalized space. The center is not.
            if (bool(medPrecision)) {
                d *= scale.y;
            }
            float2 Z = d * ellipse.zw;
            // implicit is the evaluation of (x/rx)^2 + (y/ry)^2 - 1.
            float implicit = dot(Z, d) - 1;
            // grad_dot is the squared length of the gradient of the implicit.
            float grad_dot = 4 * dot(Z, Z);
            // Avoid calling inversesqrt on zero.
            if (bool(medPrecision)) {
                grad_dot = max(grad_dot, 6.1036e-5);
            } else {
                grad_dot = max(grad_dot, 1.1755e-38);
            }
            float approx_dist = implicit * inversesqrt(grad_dot);
            if (bool(medPrecision)) {
                approx_dist *= scale.x;
            }

            half alpha;
            if (edgeType == kFillBW) {
                alpha = approx_dist > 0.0 ? 0.0 : 1.0;
            } else if (edgeType == kFillAA) {
                alpha = saturate(0.5 - half(approx_dist));
            } else if (edgeType == kInverseFillBW) {
                alpha = approx_dist > 0.0 ? 1.0 : 0.0;
            } else {  // edgeType == kInverseFillAA
                alpha = saturate(0.5 + half(approx_dist));
            }
            return inColor * alpha;
        }
    )");

    float invRXSqd;
    float invRYSqd;
    SkV2 scale = {1, 1};
    // If we're using a scale factor to work around precision issues, choose the larger radius as
    // the scale factor. The inv radii need to be pre-adjusted by the scale factor.
    if (medPrecision) {
        if (radii.fX > radii.fY) {
            invRXSqd = 1.f;
            invRYSqd = (radii.fX * radii.fX) / (radii.fY * radii.fY);
            scale = {radii.fX, 1.f / radii.fX};
        } else {
            invRXSqd = (radii.fY * radii.fY) / (radii.fX * radii.fX);
            invRYSqd = 1.f;
            scale = {radii.fY, 1.f / radii.fY};
        }
    } else {
        invRXSqd = 1.f / (radii.fX * radii.fX);
        invRYSqd = 1.f / (radii.fY * radii.fY);
    }
    SkV4 ellipse = {center.fX, center.fY, invRXSqd, invRYSqd};

    return GrFPSuccess(GrSkSLFP::Make(effect, "Ellipse", std::move(inputFP),
                                      GrSkSLFP::OptFlags::kCompatibleWithCoverageAsAlpha,
                                      "edgeType", GrSkSLFP::Specialize(static_cast<int>(edgeType)),
                                      "medPrecision",  GrSkSLFP::Specialize<int>(medPrecision),
                                      "ellipse", ellipse,
                                      "scale", scale));
}

//////////////////////////////////////////////////////////////////////////////

std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::HighPrecision(
        std::unique_ptr<GrFragmentProcessor> fp) {
    class HighPrecisionFragmentProcessor : public GrFragmentProcessor {
    public:
        static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp) {
            return std::unique_ptr<GrFragmentProcessor>(
                    new HighPrecisionFragmentProcessor(std::move(fp)));
        }

        const char* name() const override { return "HighPrecision"; }

        std::unique_ptr<GrFragmentProcessor> clone() const override {
            return Make(this->childProcessor(0)->clone());
        }

    private:
        HighPrecisionFragmentProcessor(std::unique_ptr<GrFragmentProcessor> fp)
                : INHERITED(kHighPrecisionFragmentProcessor_ClassID,
                            ProcessorOptimizationFlags(fp.get())) {
            this->registerChild(std::move(fp));
        }

        std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override {
            class Impl : public ProgramImpl {
            public:
                void emitCode(EmitArgs& args) override {
                    SkString childColor = this->invokeChild(0, args);

                    args.fFragBuilder->forceHighPrecision();
                    args.fFragBuilder->codeAppendf("return %s;", childColor.c_str());
                }
            };
            return std::make_unique<Impl>();
        }

        void onAddToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
        bool onIsEqual(const GrFragmentProcessor& other) const override { return true; }

        SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
            return ConstantOutputForConstantInput(this->childProcessor(0), input);
        }

        using INHERITED = GrFragmentProcessor;
    };

    return HighPrecisionFragmentProcessor::Make(std::move(fp));
}

//////////////////////////////////////////////////////////////////////////////

using ProgramImpl = GrFragmentProcessor::ProgramImpl;

void ProgramImpl::setData(const GrGLSLProgramDataManager& pdman,
                          const GrFragmentProcessor& processor) {
    this->onSetData(pdman, processor);
}

SkString ProgramImpl::invokeChild(int childIndex,
                                  const char* inputColor,
                                  const char* destColor,
                                  EmitArgs& args,
                                  SkSL::String skslCoords) {
    SkASSERT(childIndex >= 0);

    if (!inputColor) {
        inputColor = args.fInputColor;
    }

    const GrFragmentProcessor* childProc = args.fFp.childProcessor(childIndex);
    if (!childProc) {
        // If no child processor is provided, return the input color as-is.
        return SkString(inputColor);
    }

    auto invocation = SkStringPrintf("%s(%s", this->childProcessor(childIndex)->functionName(),
                                     inputColor);

    if (childProc->isBlendFunction()) {
        if (!destColor) {
            destColor = args.fFp.isBlendFunction() ? args.fDestColor : "half4(1)";
        }
        invocation.appendf(", %s", destColor);
    }

    // Assert that the child has no sample matrix. A uniform matrix sample call would go through
    // invokeChildWithMatrix, not here.
    SkASSERT(!childProc->sampleUsage().isUniformMatrix());

    if (args.fFragBuilder->getProgramBuilder()->fragmentProcessorHasCoordsParam(childProc)) {
        SkASSERT(!childProc->sampleUsage().isFragCoord() || skslCoords == "sk_FragCoord.xy");
        // The child's function takes a half4 color and a float2 coordinate
        invocation.appendf(", %s", skslCoords.empty() ? args.fSampleCoord : skslCoords.c_str());
    }

    invocation.append(")");
    return invocation;
}

SkString ProgramImpl::invokeChildWithMatrix(int childIndex,
                                            const char* inputColor,
                                            const char* destColor,
                                            EmitArgs& args) {
    SkASSERT(childIndex >= 0);

    if (!inputColor) {
        inputColor = args.fInputColor;
    }

    const GrFragmentProcessor* childProc = args.fFp.childProcessor(childIndex);
    if (!childProc) {
        // If no child processor is provided, return the input color as-is.
        return SkString(inputColor);
    }

    SkASSERT(childProc->sampleUsage().isUniformMatrix());

    // Every uniform matrix has the same (initial) name. Resolve that into the mangled name:
    GrShaderVar uniform = args.fUniformHandler->getUniformMapping(
            args.fFp, SkString(SkSL::SampleUsage::MatrixUniformName()));
    SkASSERT(uniform.getType() == kFloat3x3_GrSLType);
    const SkString& matrixName(uniform.getName());

    auto invocation = SkStringPrintf("%s(%s", this->childProcessor(childIndex)->functionName(),
                                     inputColor);

    if (childProc->isBlendFunction()) {
        if (!destColor) {
            destColor = args.fFp.isBlendFunction() ? args.fDestColor : "half4(1)";
        }
        invocation.appendf(", %s", destColor);
    }

    // Produce a string containing the call to the helper function. We have a uniform variable
    // containing our transform (matrixName). If the parent coords were produced by uniform
    // transforms, then the entire expression (matrixName * coords) is lifted to a vertex shader
    // and is stored in a varying. In that case, childProc will not be sampled explicitly, so its
    // function signature will not take in coords.
    //
    // In all other cases, we need to insert sksl to compute matrix * parent coords and then invoke
    // the function.
    if (args.fFragBuilder->getProgramBuilder()->fragmentProcessorHasCoordsParam(childProc)) {
        // Only check perspective for this specific matrix transform, not the aggregate FP property.
        // Any parent perspective will have already been applied when evaluated in the FS.
        if (childProc->sampleUsage().hasPerspective()) {
            invocation.appendf(", proj((%s) * %s.xy1)", matrixName.c_str(), args.fSampleCoord);
        } else if (args.fShaderCaps->nonsquareMatrixSupport()) {
            invocation.appendf(", float3x2(%s) * %s.xy1", matrixName.c_str(), args.fSampleCoord);
        } else {
            invocation.appendf(", ((%s) * %s.xy1).xy", matrixName.c_str(), args.fSampleCoord);
        }
    }

    invocation.append(")");
    return invocation;
}
