/*
 * 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 "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 GrGLSLComposeLerpRedEffect : public GrGLSLFragmentProcessor {
public:
    GrGLSLComposeLerpRedEffect() {}
    void emitCode(EmitArgs& args) override {
        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
        const GrComposeLerpRedEffect& _outer = args.fFp.cast<GrComposeLerpRedEffect>();
        (void)_outer;
        SkString _sample292;
        if (_outer.child1_index >= 0) {
            _sample292 = this->invokeChild(_outer.child1_index, args);
        } else {
            _sample292 = "half4(1)";
        }
        SkString _sample360;
        if (_outer.child2_index >= 0) {
            _sample360 = this->invokeChild(_outer.child2_index, args);
        } else {
            _sample360 = "half4(1)";
        }
        SkString _sample411;
        _sample411 = this->invokeChild(_outer.lerp_index, args);
        fragBuilder->codeAppendf("%s = mix(%s ? %s : %s, %s ? %s : %s, %s.x);\n", args.fOutputColor,
                                 _outer.child1_index >= 0 ? "true" : "false", _sample292.c_str(),
                                 args.fInputColor, _outer.child2_index >= 0 ? "true" : "false",
                                 _sample360.c_str(), args.fInputColor, _sample411.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) {
        auto clone = src.childProcessor(child1_index).clone();
        clone->setSampledWithExplicitCoords(
                src.childProcessor(child1_index).isSampledWithExplicitCoords());
        this->registerChildProcessor(std::move(clone));
    }
    if (child2_index >= 0) {
        auto clone = src.childProcessor(child2_index).clone();
        clone->setSampledWithExplicitCoords(
                src.childProcessor(child2_index).isSampledWithExplicitCoords());
        this->registerChildProcessor(std::move(clone));
    }
    {
        auto clone = src.childProcessor(lerp_index).clone();
        clone->setSampledWithExplicitCoords(
                src.childProcessor(lerp_index).isSampledWithExplicitCoords());
        this->registerChildProcessor(std::move(clone));
    }
}
std::unique_ptr<GrFragmentProcessor> GrComposeLerpRedEffect::clone() const {
    return std::unique_ptr<GrFragmentProcessor>(new GrComposeLerpRedEffect(*this));
}
