/*
 * 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 GrTiledGradientEffect.fp; do not modify.
 **************************************************************************************************/
#include "GrTiledGradientEffect.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 GrGLSLTiledGradientEffect : public GrGLSLFragmentProcessor {
public:
    GrGLSLTiledGradientEffect() {}
    void emitCode(EmitArgs& args) override {
        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
        const GrTiledGradientEffect& _outer = args.fFp.cast<GrTiledGradientEffect>();
        (void)_outer;
        auto mirror = _outer.mirror;
        (void)mirror;
        auto makePremul = _outer.makePremul;
        (void)makePremul;
        auto colorsAreOpaque = _outer.colorsAreOpaque;
        (void)colorsAreOpaque;
        SkString _sample0 = this->invokeChild(1, args);
        fragBuilder->codeAppendf(
                R"SkSL(half4 t = %s;
if (!%s && t.y < 0.0) {
    return half4(0.0);
} else {
    @if (%s) {
        half t_1 = t.x - 1.0;
        half tiled_t = (t_1 - 2.0 * floor(t_1 * 0.5)) - 1.0;
        if (sk_Caps.mustDoOpBetweenFloorAndAbs) {
            tiled_t = clamp(tiled_t, -1.0, 1.0);
        }
        t.x = abs(tiled_t);
    } else {
        t.x = fract(t.x);
    }
    @if (!%s) {)SkSL",
                _sample0.c_str(),
                (_outer.childProcessor(1)->preservesOpaqueInput() ? "true" : "false"),
                (_outer.mirror ? "true" : "false"), (_outer.makePremul ? "true" : "false"));
        SkString _coords1("float2(half2(t.x, 0.0))");
        SkString _sample1 = this->invokeChild(0, args, _coords1.c_str());
        fragBuilder->codeAppendf(
                R"SkSL(
        return %s;
    } else {)SkSL",
                _sample1.c_str());
        SkString _coords2("float2(half2(t.x, 0.0))");
        SkString _sample2 = this->invokeChild(0, args, _coords2.c_str());
        fragBuilder->codeAppendf(
                R"SkSL(
        half4 outColor = %s;
        return outColor * half4(outColor.www, 1.0);
    }
}
)SkSL",
                _sample2.c_str());
    }

private:
    void onSetData(const GrGLSLProgramDataManager& pdman,
                   const GrFragmentProcessor& _proc) override {}
};
std::unique_ptr<GrGLSLFragmentProcessor> GrTiledGradientEffect::onMakeProgramImpl() const {
    return std::make_unique<GrGLSLTiledGradientEffect>();
}
void GrTiledGradientEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                                  GrProcessorKeyBuilder* b) const {
    b->add32((uint32_t)mirror);
    b->add32((uint32_t)makePremul);
}
bool GrTiledGradientEffect::onIsEqual(const GrFragmentProcessor& other) const {
    const GrTiledGradientEffect& that = other.cast<GrTiledGradientEffect>();
    (void)that;
    if (mirror != that.mirror) return false;
    if (makePremul != that.makePremul) return false;
    if (colorsAreOpaque != that.colorsAreOpaque) return false;
    return true;
}
GrTiledGradientEffect::GrTiledGradientEffect(const GrTiledGradientEffect& src)
        : INHERITED(kGrTiledGradientEffect_ClassID, src.optimizationFlags())
        , mirror(src.mirror)
        , makePremul(src.makePremul)
        , colorsAreOpaque(src.colorsAreOpaque) {
    this->cloneAndRegisterAllChildProcessors(src);
}
std::unique_ptr<GrFragmentProcessor> GrTiledGradientEffect::clone() const {
    return std::make_unique<GrTiledGradientEffect>(*this);
}
#if GR_TEST_UTILS
SkString GrTiledGradientEffect::onDumpInfo() const {
    return SkStringPrintf("(mirror=%s, makePremul=%s, colorsAreOpaque=%s)",
                          (mirror ? "true" : "false"), (makePremul ? "true" : "false"),
                          (colorsAreOpaque ? "true" : "false"));
}
#endif
