/*
 * Copyright 2020 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 GrDeviceSpaceEffect.fp; do not modify.
 **************************************************************************************************/
#include "GrDeviceSpaceEffect.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 GrGLSLDeviceSpaceEffect : public GrGLSLFragmentProcessor {
public:
    GrGLSLDeviceSpaceEffect() {}
    void emitCode(EmitArgs& args) override {
        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
        const GrDeviceSpaceEffect& _outer = args.fFp.cast<GrDeviceSpaceEffect>();
        (void)_outer;
        SkString _input203(args.fInputColor);
        SkString _coords203("sk_FragCoord.xy");
        SkString _sample203;
        _sample203 =
                this->invokeChild(_outer.fp_index, _input203.c_str(), args, _coords203.c_str());
        fragBuilder->codeAppendf(
                R"SkSL(%s = %s;
)SkSL",
                args.fOutputColor, _sample203.c_str());
    }

private:
    void onSetData(const GrGLSLProgramDataManager& pdman,
                   const GrFragmentProcessor& _proc) override {}
};
GrGLSLFragmentProcessor* GrDeviceSpaceEffect::onCreateGLSLInstance() const {
    return new GrGLSLDeviceSpaceEffect();
}
void GrDeviceSpaceEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                                GrProcessorKeyBuilder* b) const {}
bool GrDeviceSpaceEffect::onIsEqual(const GrFragmentProcessor& other) const {
    const GrDeviceSpaceEffect& that = other.cast<GrDeviceSpaceEffect>();
    (void)that;
    return true;
}
GrDeviceSpaceEffect::GrDeviceSpaceEffect(const GrDeviceSpaceEffect& src)
        : INHERITED(kGrDeviceSpaceEffect_ClassID, src.optimizationFlags()) {
    { fp_index = this->cloneAndRegisterChildProcessor(src.childProcessor(src.fp_index)); }
}
std::unique_ptr<GrFragmentProcessor> GrDeviceSpaceEffect::clone() const {
    return std::unique_ptr<GrFragmentProcessor>(new GrDeviceSpaceEffect(*this));
}
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrDeviceSpaceEffect);
#if GR_TEST_UTILS
std::unique_ptr<GrFragmentProcessor> GrDeviceSpaceEffect::TestCreate(GrProcessorTestData* d) {
    std::unique_ptr<GrFragmentProcessor> fp;
    // We have a restriction that explicit coords only work for FPs with zero or one
    // coord transform.
    do {
        fp = GrProcessorUnitTest::MakeChildFP(d);
    } while (fp->numCoordTransforms() > 1);
    return GrDeviceSpaceEffect::Make(std::move(fp));
}
#endif
