/*
 * Copyright 2019 Google LLC.
 *
 * 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 GrComposeLerpRedEffect.fp; do not modify.
 **************************************************************************************************/
#include "GrComposeLerpRedEffect.h"
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramBuilder.h"
#include "GrTexture.h"
#include "SkSLCPP.h"
#include "SkSLUtil.h"
class GrGLSLComposeLerpRedEffect : public GrGLSLFragmentProcessor {
public:
    GrGLSLComposeLerpRedEffect() {}
    void emitCode(EmitArgs& args) override {
        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
        const GrComposeLerpRedEffect& _outer = args.fFp.cast<GrComposeLerpRedEffect>();
        (void)_outer;
        SkString _child0("_child0");
        if (_outer.child1_index >= 0) {
            this->emitChild(_outer.child1_index, &_child0, args);
        } else {
            fragBuilder->codeAppendf("half4 %s;", _child0.c_str());
        }
        SkString _child1("_child1");
        if (_outer.child2_index >= 0) {
            this->emitChild(_outer.child2_index, &_child1, args);
        } else {
            fragBuilder->codeAppendf("half4 %s;", _child1.c_str());
        }
        SkString _child2("_child2");
        this->emitChild(_outer.lerp_index, &_child2, args);
        fragBuilder->codeAppendf("%s = mix(%s ? %s : %s, %s ? %s : %s, %s.x);\n", args.fOutputColor,
                                 _outer.child1_index >= 0 ? "true" : "false", _child0.c_str(),
                                 args.fInputColor, _outer.child2_index >= 0 ? "true" : "false",
                                 _child1.c_str(), args.fInputColor, _child2.c_str());
    }

private:
    void onSetData(const GrGLSLProgramDataManager& pdman,
                   const GrFragmentProcessor& _proc) override {}
};
GrGLSLFragmentProcessor* GrComposeLerpRedEffect::onCreateGLSLInstance() const {
    return new GrGLSLComposeLerpRedEffect();
}
void GrComposeLerpRedEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                                   GrProcessorKeyBuilder* b) const {}
bool GrComposeLerpRedEffect::onIsEqual(const GrFragmentProcessor& other) const {
    const GrComposeLerpRedEffect& that = other.cast<GrComposeLerpRedEffect>();
    (void)that;
    return true;
}
GrComposeLerpRedEffect::GrComposeLerpRedEffect(const GrComposeLerpRedEffect& src)
        : INHERITED(kGrComposeLerpRedEffect_ClassID, src.optimizationFlags())
        , child1_index(src.child1_index)
        , child2_index(src.child2_index)
        , lerp_index(src.lerp_index) {
    if (child1_index >= 0) {
        this->registerChildProcessor(src.childProcessor(child1_index).clone());
    }
    if (child2_index >= 0) {
        this->registerChildProcessor(src.childProcessor(child2_index).clone());
    }
    this->registerChildProcessor(src.childProcessor(lerp_index).clone());
}
std::unique_ptr<GrFragmentProcessor> GrComposeLerpRedEffect::clone() const {
    return std::unique_ptr<GrFragmentProcessor>(new GrComposeLerpRedEffect(*this));
}
