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

/**************************************************************************************************
 *** This file was autogenerated from GrArithmeticProcessor.fp; do not modify.
 **************************************************************************************************/
#include "GrArithmeticProcessor.h"

#include "src/core/SkUtils.h"
#include "src/gpu/GrTexture.h"
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
#include "src/sksl/SkSLCPP.h"
#include "src/sksl/SkSLUtil.h"
class GrGLSLArithmeticProcessor : public GrGLSLFragmentProcessor {
public:
    GrGLSLArithmeticProcessor() {}
    void emitCode(EmitArgs& args) override {
        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
        const GrArithmeticProcessor& _outer = args.fFp.cast<GrArithmeticProcessor>();
        (void)_outer;
        auto k = _outer.k;
        (void)k;
        auto enforcePMColor = _outer.enforcePMColor;
        (void)enforcePMColor;
        kVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag, kFloat4_GrSLType,
                                                "k");
        SkString _sample385 = this->invokeChild(0, args);
        fragBuilder->codeAppendf(
                R"SkSL(half4 src = %s;)SkSL", _sample385.c_str());
        SkString _sample416 = this->invokeChild(1, args);
        fragBuilder->codeAppendf(
                R"SkSL(
half4 dst = %s;
%s = clamp((((half(%s.x) * src) * dst + half(%s.y) * src) + half(%s.z) * dst) + half(%s.w), 0.0, 1.0);
@if (%s) {
    %s.xyz = min(%s.xyz, %s.w);
}
)SkSL",
                _sample416.c_str(), args.fOutputColor, args.fUniformHandler->getUniformCStr(kVar),
                args.fUniformHandler->getUniformCStr(kVar),
                args.fUniformHandler->getUniformCStr(kVar),
                args.fUniformHandler->getUniformCStr(kVar),
                (_outer.enforcePMColor ? "true" : "false"), args.fOutputColor, args.fOutputColor,
                args.fOutputColor);
    }

private:
    void onSetData(const GrGLSLProgramDataManager& pdman,
                   const GrFragmentProcessor& _proc) override {
        const GrArithmeticProcessor& _outer = _proc.cast<GrArithmeticProcessor>();
        { pdman.set4fv(kVar, 1, (_outer.k).ptr()); }
    }
    UniformHandle kVar;
};
GrGLSLFragmentProcessor* GrArithmeticProcessor::onCreateGLSLInstance() const {
    return new GrGLSLArithmeticProcessor();
}
void GrArithmeticProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                                  GrProcessorKeyBuilder* b) const {
    b->add32((uint32_t)enforcePMColor);
}
bool GrArithmeticProcessor::onIsEqual(const GrFragmentProcessor& other) const {
    const GrArithmeticProcessor& that = other.cast<GrArithmeticProcessor>();
    (void)that;
    if (k != that.k) return false;
    if (enforcePMColor != that.enforcePMColor) return false;
    return true;
}
bool GrArithmeticProcessor::usesExplicitReturn() const { return false; }
GrArithmeticProcessor::GrArithmeticProcessor(const GrArithmeticProcessor& src)
        : INHERITED(kGrArithmeticProcessor_ClassID, src.optimizationFlags())
        , k(src.k)
        , enforcePMColor(src.enforcePMColor) {
    this->cloneAndRegisterAllChildProcessors(src);
}
std::unique_ptr<GrFragmentProcessor> GrArithmeticProcessor::clone() const {
    return std::make_unique<GrArithmeticProcessor>(*this);
}
#if GR_TEST_UTILS
SkString GrArithmeticProcessor::onDumpInfo() const {
    return SkStringPrintf("(k=float4(%f, %f, %f, %f), enforcePMColor=%s)", k.x, k.y, k.z, k.w,
                          (enforcePMColor ? "true" : "false"));
}
#endif
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrArithmeticProcessor);
#if GR_TEST_UTILS
std::unique_ptr<GrFragmentProcessor> GrArithmeticProcessor::TestCreate(GrProcessorTestData* d) {
    return GrArithmeticProcessor::Make(
            GrProcessorUnitTest::MakeChildFP(d), GrProcessorUnitTest::MakeChildFP(d),
            ArithmeticFPInputs{d->fRandom->nextF(), d->fRandom->nextF(), d->fRandom->nextF(),
                               d->fRandom->nextF(), d->fRandom->nextBool()});
}
#endif
