/*
 * 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 GrMatrixEffect.fp; do not modify.
 **************************************************************************************************/
#include "GrMatrixEffect.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 GrGLSLMatrixEffect : public GrGLSLFragmentProcessor {
public:
    GrGLSLMatrixEffect() {}
    void emitCode(EmitArgs& args) override {
        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
        const GrMatrixEffect& _outer = args.fFp.cast<GrMatrixEffect>();
        (void)_outer;
        auto matrix = _outer.matrix;
        (void)matrix;
        matrixVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag,
                                                     kFloat3x3_GrSLType, "matrix");
        SkString _input716 = SkStringPrintf("%s", args.fInputColor);
        SkString _sample716;
        _sample716 = this->invokeChild(_outer.child_index, _input716.c_str(), args);
        fragBuilder->codeAppendf("%s = %s;\n", args.fOutputColor, _sample716.c_str());
    }

private:
    void onSetData(const GrGLSLProgramDataManager& pdman,
                   const GrFragmentProcessor& _proc) override {
        const GrMatrixEffect& _outer = _proc.cast<GrMatrixEffect>();
        { pdman.setSkMatrix(matrixVar, (_outer.matrix)); }
    }
    UniformHandle matrixVar;
};
GrGLSLFragmentProcessor* GrMatrixEffect::onCreateGLSLInstance() const {
    return new GrGLSLMatrixEffect();
}
void GrMatrixEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                           GrProcessorKeyBuilder* b) const {}
bool GrMatrixEffect::onIsEqual(const GrFragmentProcessor& other) const {
    const GrMatrixEffect& that = other.cast<GrMatrixEffect>();
    (void)that;
    if (matrix != that.matrix) return false;
    return true;
}
GrMatrixEffect::GrMatrixEffect(const GrMatrixEffect& src)
        : INHERITED(kGrMatrixEffect_ClassID, src.optimizationFlags())
        , matrix(src.matrix)
        , child_index(src.child_index) {
    {
        auto clone = src.childProcessor(child_index).clone();
        if (src.childProcessor(child_index).isSampledWithExplicitCoords()) {
            clone->setSampledWithExplicitCoords();
        }
        this->registerChildProcessor(std::move(clone));
    }
}
std::unique_ptr<GrFragmentProcessor> GrMatrixEffect::clone() const {
    return std::unique_ptr<GrFragmentProcessor>(new GrMatrixEffect(*this));
}
