

/**************************************************************************************************
 *** This file was autogenerated from GrDSLFPTest_SwitchStatement.fp; do not modify.
 **************************************************************************************************/
/* TODO(skia:11854): DSLCPPCodeGenerator is currently a work in progress. */
#include "GrDSLFPTest_SwitchStatement.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"
#include "src/sksl/dsl/priv/DSLFPs.h"
#include "src/sksl/dsl/priv/DSLWriter.h"

class GrGLSLDSLFPTest_SwitchStatement : public GrGLSLFragmentProcessor {
public:
    GrGLSLDSLFPTest_SwitchStatement() {}
    void emitCode(EmitArgs& args) override {
        [[maybe_unused]] const GrDSLFPTest_SwitchStatement& _outer = args.fFp.cast<GrDSLFPTest_SwitchStatement>();

        using namespace SkSL::dsl;
        StartFragmentProcessor(this, &args);
[[maybe_unused]] const auto& ten = _outer.ten;
Var _ten(kConst_Modifier, DSLType(kInt_Type), "ten", Int(ten));
Declare(_ten);
Var _color(kNo_Modifier, DSLType(kInt4_Type), "color", Int4(0));
Declare(_color);
Switch(_color.x(),
    Case(0, ++_color.y()),
    Case(1, Break()),
    Case(2, Return(Half4(0.0f))),
    Case(3),
    Case(4, ++_color.x()),
    Case(5, Block(++_color.z()), Break()),
    Default(Block(--_color.y(), Break())));
Switch(_color.y(),
    Case(1, Break()),
    Case(0, Block(_color.x() = 1, _color.z() = 1)));
StaticSwitch(_ten,
    Case(0, _color.x() = _color.y(), Break()),
    Case(20, _color.z() = _color.y(), Break()),
    Case(10, _color.w() = _color.y(), Break()));
Return(Half4(_color));
        EndFragmentProcessor();
    }
private:
    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
    }
};
std::unique_ptr<GrGLSLFragmentProcessor> GrDSLFPTest_SwitchStatement::onMakeProgramImpl() const {
    return std::make_unique<GrGLSLDSLFPTest_SwitchStatement>();
}
void GrDSLFPTest_SwitchStatement::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
    b->add32((uint32_t) ten, "ten");
}
bool GrDSLFPTest_SwitchStatement::onIsEqual(const GrFragmentProcessor& other) const {
    const GrDSLFPTest_SwitchStatement& that = other.cast<GrDSLFPTest_SwitchStatement>();
    (void) that;
    if (ten != that.ten) return false;
    return true;
}
GrDSLFPTest_SwitchStatement::GrDSLFPTest_SwitchStatement(const GrDSLFPTest_SwitchStatement& src)
: INHERITED(kGrDSLFPTest_SwitchStatement_ClassID, src.optimizationFlags())
, ten(src.ten) {
        this->cloneAndRegisterAllChildProcessors(src);
}
std::unique_ptr<GrFragmentProcessor> GrDSLFPTest_SwitchStatement::clone() const {
    return std::make_unique<GrDSLFPTest_SwitchStatement>(*this);
}
#if GR_TEST_UTILS
SkString GrDSLFPTest_SwitchStatement::onDumpInfo() const {
    return SkStringPrintf("(ten=%d)", ten);
}
#endif
