/*
 * 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 GrOverdrawFragmentProcessor.fp; do not modify.
 **************************************************************************************************/
#include "GrOverdrawFragmentProcessor.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 GrGLSLOverdrawFragmentProcessor : public GrGLSLFragmentProcessor {
public:
    GrGLSLOverdrawFragmentProcessor() {}
    void emitCode(EmitArgs& args) override {
        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
        const GrOverdrawFragmentProcessor& _outer = args.fFp.cast<GrOverdrawFragmentProcessor>();
        (void)_outer;
        auto color0 = _outer.color0();
        (void)color0;
        auto color1 = _outer.color1();
        (void)color1;
        auto color2 = _outer.color2();
        (void)color2;
        auto color3 = _outer.color3();
        (void)color3;
        auto color4 = _outer.color4();
        (void)color4;
        auto color5 = _outer.color5();
        (void)color5;
        fragBuilder->codeAppendf(
                "half alpha = half(255.0 * float(%s.w));\nif (float(alpha) < 0.5) {\n    %s = "
                "half4(%f, %f, %f, %f);\n} else if (float(alpha) < 1.5) {\n    %s = half4(%f, %f, "
                "%f, %f);\n} else if (float(alpha) < 2.5) {\n    %s = half4(%f, %f, %f, %f);\n} "
                "else if (float(alpha) < 3.5) {\n    %s = half4(%f, %f, %f, %f);\n} else if "
                "(float(alpha) < 4.5) {\n    %s = half4(%f, %f, %f, %f);\n} else {\n    %s = "
                "half4(%f, %f, %f, %f);\n}\n",
                args.fInputColor ? args.fInputColor : "half4(1)", args.fOutputColor,
                SkGetPackedR32(_outer.color0()) / 255.0, SkGetPackedG32(_outer.color0()) / 255.0,
                SkGetPackedB32(_outer.color0()) / 255.0, SkGetPackedA32(_outer.color0()) / 255.0,
                args.fOutputColor, SkGetPackedR32(_outer.color1()) / 255.0,
                SkGetPackedG32(_outer.color1()) / 255.0, SkGetPackedB32(_outer.color1()) / 255.0,
                SkGetPackedA32(_outer.color1()) / 255.0, args.fOutputColor,
                SkGetPackedR32(_outer.color2()) / 255.0, SkGetPackedG32(_outer.color2()) / 255.0,
                SkGetPackedB32(_outer.color2()) / 255.0, SkGetPackedA32(_outer.color2()) / 255.0,
                args.fOutputColor, SkGetPackedR32(_outer.color3()) / 255.0,
                SkGetPackedG32(_outer.color3()) / 255.0, SkGetPackedB32(_outer.color3()) / 255.0,
                SkGetPackedA32(_outer.color3()) / 255.0, args.fOutputColor,
                SkGetPackedR32(_outer.color4()) / 255.0, SkGetPackedG32(_outer.color4()) / 255.0,
                SkGetPackedB32(_outer.color4()) / 255.0, SkGetPackedA32(_outer.color4()) / 255.0,
                args.fOutputColor, SkGetPackedR32(_outer.color5()) / 255.0,
                SkGetPackedG32(_outer.color5()) / 255.0, SkGetPackedB32(_outer.color5()) / 255.0,
                SkGetPackedA32(_outer.color5()) / 255.0);
    }

private:
    void onSetData(const GrGLSLProgramDataManager& pdman,
                   const GrFragmentProcessor& _proc) override {}
};
GrGLSLFragmentProcessor* GrOverdrawFragmentProcessor::onCreateGLSLInstance() const {
    return new GrGLSLOverdrawFragmentProcessor();
}
void GrOverdrawFragmentProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                                        GrProcessorKeyBuilder* b) const {}
bool GrOverdrawFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const {
    const GrOverdrawFragmentProcessor& that = other.cast<GrOverdrawFragmentProcessor>();
    (void)that;
    if (fColor0 != that.fColor0) return false;
    if (fColor1 != that.fColor1) return false;
    if (fColor2 != that.fColor2) return false;
    if (fColor3 != that.fColor3) return false;
    if (fColor4 != that.fColor4) return false;
    if (fColor5 != that.fColor5) return false;
    return true;
}
GrOverdrawFragmentProcessor::GrOverdrawFragmentProcessor(const GrOverdrawFragmentProcessor& src)
        : INHERITED(kGrOverdrawFragmentProcessor_ClassID, src.optimizationFlags())
        , fColor0(src.fColor0)
        , fColor1(src.fColor1)
        , fColor2(src.fColor2)
        , fColor3(src.fColor3)
        , fColor4(src.fColor4)
        , fColor5(src.fColor5) {}
std::unique_ptr<GrFragmentProcessor> GrOverdrawFragmentProcessor::clone() const {
    return std::unique_ptr<GrFragmentProcessor>(new GrOverdrawFragmentProcessor(*this));
}
#endif
