/*
 * Copyright 2017 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 GrBlurredEdgeFragmentProcessor.fp; do not modify.
 **************************************************************************************************/
#include "GrBlurredEdgeFragmentProcessor.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 GrGLSLBlurredEdgeFragmentProcessor : public GrGLSLFragmentProcessor {
public:
    GrGLSLBlurredEdgeFragmentProcessor() {}
    void emitCode(EmitArgs& args) override {
        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
        const GrBlurredEdgeFragmentProcessor& _outer =
                args.fFp.cast<GrBlurredEdgeFragmentProcessor>();
        (void)_outer;
        auto mode = _outer.mode;
        (void)mode;
        SkString _sample328;
        if (_outer.inputFP_index >= 0) {
            _sample328 = this->invokeChild(_outer.inputFP_index, args);
        } else {
            _sample328 = "half4(1)";
        }
        fragBuilder->codeAppendf(
                "half inputAlpha = %s ? %s.w : %s.w;\nhalf factor = 1.0 - inputAlpha;\n@switch "
                "(%d) {\n    case 0:\n        factor = exp((-factor * factor) * 4.0) - "
                "0.017999999225139618;\n        break;\n    case 1:\n        factor = "
                "smoothstep(1.0, 0.0, factor);\n        break;\n}\n%s = half4(factor);\n",
                _outer.inputFP_index >= 0 ? "true" : "false", _sample328.c_str(), args.fInputColor,
                (int)_outer.mode, args.fOutputColor);
    }

private:
    void onSetData(const GrGLSLProgramDataManager& pdman,
                   const GrFragmentProcessor& _proc) override {}
};
GrGLSLFragmentProcessor* GrBlurredEdgeFragmentProcessor::onCreateGLSLInstance() const {
    return new GrGLSLBlurredEdgeFragmentProcessor();
}
void GrBlurredEdgeFragmentProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                                           GrProcessorKeyBuilder* b) const {
    b->add32((int32_t)mode);
}
bool GrBlurredEdgeFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const {
    const GrBlurredEdgeFragmentProcessor& that = other.cast<GrBlurredEdgeFragmentProcessor>();
    (void)that;
    if (mode != that.mode) return false;
    return true;
}
GrBlurredEdgeFragmentProcessor::GrBlurredEdgeFragmentProcessor(
        const GrBlurredEdgeFragmentProcessor& src)
        : INHERITED(kGrBlurredEdgeFragmentProcessor_ClassID, src.optimizationFlags())
        , inputFP_index(src.inputFP_index)
        , mode(src.mode) {
    if (inputFP_index >= 0) {
        auto clone = src.childProcessor(inputFP_index).clone();
        if (src.childProcessor(inputFP_index).isSampledWithExplicitCoords()) {
            clone->setSampledWithExplicitCoords();
        }
        this->registerChildProcessor(std::move(clone));
    }
}
std::unique_ptr<GrFragmentProcessor> GrBlurredEdgeFragmentProcessor::clone() const {
    return std::unique_ptr<GrFragmentProcessor>(new GrBlurredEdgeFragmentProcessor(*this));
}
