/*
 * Copyright 2018 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 GrArithmeticFP.fp; do not modify.
 **************************************************************************************************/
#include "GrArithmeticFP.h"
#if SK_SUPPORT_GPU
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramBuilder.h"
#include "GrTexture.h"
#include "SkSLCPP.h"
#include "SkSLUtil.h"
class GrGLSLArithmeticFP : public GrGLSLFragmentProcessor {
public:
    GrGLSLArithmeticFP() {}
    void emitCode(EmitArgs& args) override {
        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
        const GrArithmeticFP& _outer = args.fFp.cast<GrArithmeticFP>();
        (void)_outer;
        auto k1 = _outer.k1();
        (void)k1;
        auto k2 = _outer.k2();
        (void)k2;
        auto k3 = _outer.k3();
        (void)k3;
        auto k4 = _outer.k4();
        (void)k4;
        auto enforcePMColor = _outer.enforcePMColor();
        (void)enforcePMColor;
        fKVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType,
                                                 kDefault_GrSLPrecision, "k");
        SkString _child0("_child0");
        this->emitChild(0, &_child0, args);
        fragBuilder->codeAppendf(
                "half4 dst = %s;\n%s = half4(clamp(float4(float4(((%s.x * float4(%s)) * dst + %s.y "
                "* float4(%s)) + %s.z * float4(dst)) + %s.w), 0.0, 1.0));\nif (%s) {\n    %s.xyz = "
                "half3(min(float3(%s.xyz), float(%s.w)));\n}\n",
                _child0.c_str(), args.fOutputColor, args.fUniformHandler->getUniformCStr(fKVar),
                args.fInputColor ? args.fInputColor : "half4(1)",
                args.fUniformHandler->getUniformCStr(fKVar),
                args.fInputColor ? args.fInputColor : "half4(1)",
                args.fUniformHandler->getUniformCStr(fKVar),
                args.fUniformHandler->getUniformCStr(fKVar),
                (_outer.enforcePMColor() ? "true" : "false"), args.fOutputColor, args.fOutputColor,
                args.fOutputColor);
    }

private:
    void onSetData(const GrGLSLProgramDataManager& pdman,
                   const GrFragmentProcessor& _proc) override {
        const GrArithmeticFP& _outer = _proc.cast<GrArithmeticFP>();
        auto k1 = _outer.k1();
        (void)k1;
        auto k2 = _outer.k2();
        (void)k2;
        auto k3 = _outer.k3();
        (void)k3;
        auto k4 = _outer.k4();
        (void)k4;
        auto enforcePMColor = _outer.enforcePMColor();
        (void)enforcePMColor;
        UniformHandle& k = fKVar;
        (void)k;

        pdman.set4f(k, k1, k2, k3, k4);
    }
    UniformHandle fKVar;
};
GrGLSLFragmentProcessor* GrArithmeticFP::onCreateGLSLInstance() const {
    return new GrGLSLArithmeticFP();
}
void GrArithmeticFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                           GrProcessorKeyBuilder* b) const {
    b->add32((int32_t)fEnforcePMColor);
}
bool GrArithmeticFP::onIsEqual(const GrFragmentProcessor& other) const {
    const GrArithmeticFP& that = other.cast<GrArithmeticFP>();
    (void)that;
    if (fK1 != that.fK1) return false;
    if (fK2 != that.fK2) return false;
    if (fK3 != that.fK3) return false;
    if (fK4 != that.fK4) return false;
    if (fEnforcePMColor != that.fEnforcePMColor) return false;
    return true;
}
GrArithmeticFP::GrArithmeticFP(const GrArithmeticFP& src)
        : INHERITED(kGrArithmeticFP_ClassID, src.optimizationFlags())
        , fK1(src.fK1)
        , fK2(src.fK2)
        , fK3(src.fK3)
        , fK4(src.fK4)
        , fEnforcePMColor(src.fEnforcePMColor) {
    this->registerChildProcessor(src.childProcessor(0).clone());
}
std::unique_ptr<GrFragmentProcessor> GrArithmeticFP::clone() const {
    return std::unique_ptr<GrFragmentProcessor>(new GrArithmeticFP(*this));
}
#endif
