/*
 * 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 GrDualIntervalGradientColorizer.fp; do not modify.
 **************************************************************************************************/
#include "GrDualIntervalGradientColorizer.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 GrGLSLDualIntervalGradientColorizer : public GrGLSLFragmentProcessor {
public:
    GrGLSLDualIntervalGradientColorizer() {}
    void emitCode(EmitArgs& args) override {
        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
        const GrDualIntervalGradientColorizer& _outer =
                args.fFp.cast<GrDualIntervalGradientColorizer>();
        (void)_outer;
        auto scale01 = _outer.scale01;
        (void)scale01;
        auto bias01 = _outer.bias01;
        (void)bias01;
        auto scale23 = _outer.scale23;
        (void)scale23;
        auto bias23 = _outer.bias23;
        (void)bias23;
        auto threshold = _outer.threshold;
        (void)threshold;
        scale01Var = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag,
                                                      kFloat4_GrSLType, "scale01");
        bias01Var = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag,
                                                     kFloat4_GrSLType, "bias01");
        scale23Var = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag,
                                                      kFloat4_GrSLType, "scale23");
        bias23Var = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag,
                                                     kFloat4_GrSLType, "bias23");
        thresholdVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag,
                                                        kHalf_GrSLType, "threshold");
        fragBuilder->codeAppendf(
                R"SkSL(half t = half(%s.x);
float4 scale, bias;
if (t < %s) {
    scale = %s;
    bias = %s;
} else {
    scale = %s;
    bias = %s;
}
%s = half4(float(t) * scale + bias);
)SkSL",
                args.fSampleCoord, args.fUniformHandler->getUniformCStr(thresholdVar),
                args.fUniformHandler->getUniformCStr(scale01Var),
                args.fUniformHandler->getUniformCStr(bias01Var),
                args.fUniformHandler->getUniformCStr(scale23Var),
                args.fUniformHandler->getUniformCStr(bias23Var), args.fOutputColor);
    }

private:
    void onSetData(const GrGLSLProgramDataManager& pdman,
                   const GrFragmentProcessor& _proc) override {
        const GrDualIntervalGradientColorizer& _outer =
                _proc.cast<GrDualIntervalGradientColorizer>();
        {
            const SkPMColor4f& scale01Value = _outer.scale01;
            if (scale01Prev != scale01Value) {
                scale01Prev = scale01Value;
                pdman.set4fv(scale01Var, 1, scale01Value.vec());
            }
            const SkPMColor4f& bias01Value = _outer.bias01;
            if (bias01Prev != bias01Value) {
                bias01Prev = bias01Value;
                pdman.set4fv(bias01Var, 1, bias01Value.vec());
            }
            const SkPMColor4f& scale23Value = _outer.scale23;
            if (scale23Prev != scale23Value) {
                scale23Prev = scale23Value;
                pdman.set4fv(scale23Var, 1, scale23Value.vec());
            }
            const SkPMColor4f& bias23Value = _outer.bias23;
            if (bias23Prev != bias23Value) {
                bias23Prev = bias23Value;
                pdman.set4fv(bias23Var, 1, bias23Value.vec());
            }
            float thresholdValue = _outer.threshold;
            if (thresholdPrev != thresholdValue) {
                thresholdPrev = thresholdValue;
                pdman.set1f(thresholdVar, thresholdValue);
            }
        }
    }
    SkPMColor4f scale01Prev = {SK_FloatNaN, SK_FloatNaN, SK_FloatNaN, SK_FloatNaN};
    SkPMColor4f bias01Prev = {SK_FloatNaN, SK_FloatNaN, SK_FloatNaN, SK_FloatNaN};
    SkPMColor4f scale23Prev = {SK_FloatNaN, SK_FloatNaN, SK_FloatNaN, SK_FloatNaN};
    SkPMColor4f bias23Prev = {SK_FloatNaN, SK_FloatNaN, SK_FloatNaN, SK_FloatNaN};
    float thresholdPrev = SK_FloatNaN;
    UniformHandle scale01Var;
    UniformHandle bias01Var;
    UniformHandle scale23Var;
    UniformHandle bias23Var;
    UniformHandle thresholdVar;
};
GrGLSLFragmentProcessor* GrDualIntervalGradientColorizer::onCreateGLSLInstance() const {
    return new GrGLSLDualIntervalGradientColorizer();
}
void GrDualIntervalGradientColorizer::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                                            GrProcessorKeyBuilder* b) const {}
bool GrDualIntervalGradientColorizer::onIsEqual(const GrFragmentProcessor& other) const {
    const GrDualIntervalGradientColorizer& that = other.cast<GrDualIntervalGradientColorizer>();
    (void)that;
    if (scale01 != that.scale01) return false;
    if (bias01 != that.bias01) return false;
    if (scale23 != that.scale23) return false;
    if (bias23 != that.bias23) return false;
    if (threshold != that.threshold) return false;
    return true;
}
GrDualIntervalGradientColorizer::GrDualIntervalGradientColorizer(
        const GrDualIntervalGradientColorizer& src)
        : INHERITED(kGrDualIntervalGradientColorizer_ClassID, src.optimizationFlags())
        , scale01(src.scale01)
        , bias01(src.bias01)
        , scale23(src.scale23)
        , bias23(src.bias23)
        , threshold(src.threshold) {
    this->cloneAndRegisterAllChildProcessors(src);
    this->setUsesSampleCoordsDirectly();
}
std::unique_ptr<GrFragmentProcessor> GrDualIntervalGradientColorizer::clone() const {
    return std::unique_ptr<GrFragmentProcessor>(new GrDualIntervalGradientColorizer(*this));
}

std::unique_ptr<GrFragmentProcessor> GrDualIntervalGradientColorizer::Make(const SkPMColor4f& c0,
                                                                           const SkPMColor4f& c1,
                                                                           const SkPMColor4f& c2,
                                                                           const SkPMColor4f& c3,
                                                                           float threshold) {
    // Derive scale and biases from the 4 colors and threshold
    auto vc0 = Sk4f::Load(c0.vec());
    auto vc1 = Sk4f::Load(c1.vec());
    auto scale01 = (vc1 - vc0) / threshold;
    // bias01 = c0

    auto vc2 = Sk4f::Load(c2.vec());
    auto vc3 = Sk4f::Load(c3.vec());
    auto scale23 = (vc3 - vc2) / (1 - threshold);
    auto bias23 = vc2 - threshold * scale23;

    return std::unique_ptr<GrFragmentProcessor>(new GrDualIntervalGradientColorizer(
            {scale01[0], scale01[1], scale01[2], scale01[3]}, c0,
            {scale23[0], scale23[1], scale23[2], scale23[3]},
            {bias23[0], bias23[1], bias23[2], bias23[3]}, threshold));
}
