/*
 * Copyright 2019 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/SkCanvas.h"
#include "include/core/SkData.h"
#include "include/core/SkPaint.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/effects/SkRuntimeEffect.h"

static const char* RUNTIME_FUNCTIONS_SRC = R"(
    uniform half4 gColor;

    half scale(float x) {
        return half(x) / 255;
    }

    half4 blackAndWhite(half4 raw) {
        half value = raw.r * 0.22 + raw.g * 0.67 + raw.b * 0.11;
        return half4(half3(value), raw.a);
    }

    void main(float2 p, inout half4 color) {
        color = blackAndWhite(half4(scale(p.x), scale(p.y), gColor.b, 1));
    }
)";

class RuntimeFunctions : public skiagm::GM {
    bool runAsBench() const override { return true; }

    SkString onShortName() override { return SkString("runtimefunctions"); }

    SkISize onISize() override { return {256, 256}; }

    void onDraw(SkCanvas* canvas) override {
        sk_sp<SkRuntimeEffect> gEffect =
                std::get<0>(SkRuntimeEffect::Make(SkString(RUNTIME_FUNCTIONS_SRC)));
        SkASSERT(gEffect);

        SkMatrix localM;
        localM.setRotate(90, 128, 128);

        SkColor4f inputColor = { 1, 0, 0, 1 };
        auto shader = gEffect->makeShader(SkData::MakeWithCopy(&inputColor, sizeof(inputColor)),
                                          nullptr, 0, &localM, true);
        SkPaint p;
        p.setShader(std::move(shader));
        canvas->drawRect({0, 0, 256, 256}, p);
    }
};

DEF_GM(return new RuntimeFunctions;)
