/*
 * Copyright 2021 Google LLC.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm/gm.h"
#include "include/core/SkFont.h"
#include "include/effects/SkRuntimeEffect.h"
#include "src/gpu/GrBitmapTextureMaker.h"
#include "src/gpu/GrDirectContextPriv.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/ops/GrFillRectOp.h"
#include "src/sksl/dsl/priv/DSLFPs.h"
#include "tools/ToolUtils.h"

class SimpleDSLEffect : public GrFragmentProcessor {
public:
    static constexpr GrProcessor::ClassID CLASS_ID = (GrProcessor::ClassID) 100;

    SimpleDSLEffect() : GrFragmentProcessor(CLASS_ID, kNone_OptimizationFlags) {
    }

    const char* name() const override { return "DSLEffect"; }
    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
    bool onIsEqual(const GrFragmentProcessor& that) const override { return this == &that; }
    std::unique_ptr<GrFragmentProcessor> clone() const override { return nullptr; }

    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
        class Impl : public GrGLSLFragmentProcessor {
            void emitCode(EmitArgs& args) override {
                using namespace SkSL::dsl;
                StartFragmentProcessor(this, &args);
                Var blueAlpha(kUniform_Modifier, kHalf2);
                fBlueAlphaUniform = VarUniformHandle(blueAlpha);
                Var coords(kFloat4);
                args.fFragBuilder->codeAppend(Declare(coords, sk_FragCoord()));
                args.fFragBuilder->codeAppend(Return(Half4(Swizzle(coords, X, Y) / 100,
                                                           blueAlpha)));
                EndFragmentProcessor();
            }

            void onSetData(const GrGLSLProgramDataManager& pdman,
                           const GrFragmentProcessor& effect) override {
                pdman.set2f(fBlueAlphaUniform, 0.0, 1.0);
            }

            GrGLSLProgramDataManager::UniformHandle fBlueAlphaUniform;
        };
        return new Impl;
    }
};

DEF_SIMPLE_GPU_GM(simple_dsl_test, ctx, rtCtx, canvas, 100, 100) {
    auto fp = std::make_unique<SimpleDSLEffect>();
    GrPaint paint;
    paint.setColorFragmentProcessor(std::move(fp));
    rtCtx->drawRect(nullptr, std::move(paint), GrAA::kNo, SkMatrix::I(),
                    SkRect::MakeIWH(100, 100));
}
