/*
 * 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 "bench/Benchmark.h"
#include "bench/ResultsWriter.h"
#include "bench/SkSLBench.h"
#include "src/sksl/SkSLCompiler.h"

class SkSLCompilerStartupBench : public Benchmark {
protected:
    const char* onGetName() override {
        return "sksl_compiler_startup";
    }

    bool isSuitableFor(Backend backend) override {
        return backend == kNonRendering_Backend;
    }

    void onDraw(int loops, SkCanvas*) override {
        for (int i = 0; i < loops; i++) {
            SkSL::Compiler compiler;
        }
    }
};

DEF_BENCH(return new SkSLCompilerStartupBench();)

class SkSLBench : public Benchmark {
public:
    SkSLBench(SkSL::String name, const char* src)
        : fName("sksl_" + name)
        , fSrc(src) {}

protected:
    const char* onGetName() override {
        return fName.c_str();
    }

    bool isSuitableFor(Backend backend) override {
        return backend == kNonRendering_Backend;
    }

    void onDraw(int loops, SkCanvas*) override {
        for (int i = 0; i < loops; i++) {
            std::unique_ptr<SkSL::Program> program = fCompiler.convertProgram(
                                                                      SkSL::Program::kFragment_Kind,
                                                                      fSrc,
                                                                      fSettings);
            if (fCompiler.errorCount()) {
                printf("%s\n", fCompiler.errorText().c_str());
                SK_ABORT("shader compilation failed");
            }
        }
    }

private:
    SkSL::String fName;
    SkSL::String fSrc;
    SkSL::Compiler fCompiler;
    SkSL::Program::Settings fSettings;

    using INHERITED = Benchmark;
};

///////////////////////////////////////////////////////////////////////////////

DEF_BENCH(return new SkSLBench("tiny", "void main() { sk_FragColor = half4(1); }"); )
DEF_BENCH(return new SkSLBench("large", R"(
uniform half urange_Stage1;
uniform half4 uleftBorderColor_Stage1_c0_c0;
uniform half4 urightBorderColor_Stage1_c0_c0;
uniform float3x3 umatrix_Stage1_c0_c0_c0;
uniform half2 ufocalParams_Stage1_c0_c0_c0_c0;
uniform float4 uscale0_1_Stage1_c0_c0_c1;
uniform float4 uscale2_3_Stage1_c0_c0_c1;
uniform float4 uscale4_5_Stage1_c0_c0_c1;
uniform float4 uscale6_7_Stage1_c0_c0_c1;
uniform float4 ubias0_1_Stage1_c0_c0_c1;
uniform float4 ubias2_3_Stage1_c0_c0_c1;
uniform float4 ubias4_5_Stage1_c0_c0_c1;
uniform float4 ubias6_7_Stage1_c0_c0_c1;
uniform half4 uthresholds1_7_Stage1_c0_c0_c1;
uniform half4 uthresholds9_13_Stage1_c0_c0_c1;
flat in half4 vcolor_Stage0;
in float vcoverage_Stage0;
flat in float4 vgeomSubset_Stage0;
in float2 vTransformedCoords_0_Stage0;
out half4 sk_FragColor;
half4 TwoPointConicalGradientLayout_Stage1_c0_c0_c0_c0(half4 _input)
{
    half4 _output;
    float t = -1.0;
    half v = 1.0;
    @switch (2)
    {
        case 1:
        {
            half r0_2 = ufocalParams_Stage1_c0_c0_c0_c0.y;
            t = float(r0_2) - vTransformedCoords_0_Stage0.y * vTransformedCoords_0_Stage0.y;
            if (t >= 0.0)
            {
                t = vTransformedCoords_0_Stage0.x + sqrt(t);
            }
            else
            {
                v = -1.0;
            }
        }
        break;
        case 0:
        {
            half r0 = ufocalParams_Stage1_c0_c0_c0_c0.x;
            @if (true)
            {
                t = length(vTransformedCoords_0_Stage0) - float(r0);
            }
            else
            {
                t = -length(vTransformedCoords_0_Stage0) - float(r0);
            }
        }
        break;
        case 2:
        {
            half invR1 = ufocalParams_Stage1_c0_c0_c0_c0.x;
            half fx = ufocalParams_Stage1_c0_c0_c0_c0.y;
            float x_t = -1.0;
            @if (false)
            {
                x_t = dot(vTransformedCoords_0_Stage0, vTransformedCoords_0_Stage0) / vTransformedCoords_0_Stage0.x;
            }
            else if (true)
            {
                x_t = length(vTransformedCoords_0_Stage0) - vTransformedCoords_0_Stage0.x * float(invR1);
            }
            else
            {
                float temp = vTransformedCoords_0_Stage0.x * vTransformedCoords_0_Stage0.x - vTransformedCoords_0_Stage0.y * vTransformedCoords_0_Stage0.y;
                if (temp >= 0.0)
                {
                    @if (false || !true)
                    {
                        x_t = -sqrt(temp) - vTransformedCoords_0_Stage0.x * float(invR1);
                    }
                    else
                    {
                        x_t = sqrt(temp) - vTransformedCoords_0_Stage0.x * float(invR1);
                    }
                }
            }
            @if (!true)
            {
                if (x_t <= 0.0)
                {
                    v = -1.0;
                }
            }
            @if (true)
            {
                @if (false)
                {
                    t = x_t;
                }
                else
                {
                    t = x_t + float(fx);
                }
            }
            else
            {
                @if (false)
                {
                    t = -x_t;
                }
                else
                {
                    t = -x_t + float(fx);
                }
            }
            @if (false)
            {
                t = 1.0 - t;
            }
        }
        break;
    }
    _output = half4(half(t), v, 0.0, 0.0);
    return _output;
}
half4 MatrixEffect_Stage1_c0_c0_c0(half4 _input)
{
    half4 _output;
    _output = TwoPointConicalGradientLayout_Stage1_c0_c0_c0_c0(_input);
    return _output;
}
half4 UnrolledBinaryGradientColorizer_Stage1_c0_c0_c1(half4 _input, float2 _coords)
{
    half4 _output;
    half t = half(_coords.x);
    float4 scale, bias;
    if (4 <= 4 || t < uthresholds1_7_Stage1_c0_c0_c1.w)
    {
        if (4 <= 2 || t < uthresholds1_7_Stage1_c0_c0_c1.y)
        {
            if (4 <= 1 || t < uthresholds1_7_Stage1_c0_c0_c1.x)
            {
                scale = uscale0_1_Stage1_c0_c0_c1;
                bias = ubias0_1_Stage1_c0_c0_c1;
            }
            else
            {
                scale = uscale2_3_Stage1_c0_c0_c1;
                bias = ubias2_3_Stage1_c0_c0_c1;
            }
        }
        else
        {
            if (4 <= 3 || t < uthresholds1_7_Stage1_c0_c0_c1.z)
            {
                scale = uscale4_5_Stage1_c0_c0_c1;
                bias = ubias4_5_Stage1_c0_c0_c1;
            }
            else
            {
                scale = uscale6_7_Stage1_c0_c0_c1;
                bias = ubias6_7_Stage1_c0_c0_c1;
            }
        }
    }
    else
    {
        if (4 <= 6 || t < uthresholds9_13_Stage1_c0_c0_c1.y)
        {
            if (4 <= 5 || t < uthresholds9_13_Stage1_c0_c0_c1.x)
            {
                scale = float4(0);
                bias = float4(0);
            }
            else
            {
                scale = float4(0);
                bias = float4(0);
            }
        }
        else
        {
            if (4 <= 7 || t < uthresholds9_13_Stage1_c0_c0_c1.z)
            {
                scale = float4(0);
                bias = float4(0);
            }
            else
            {
                scale = float4(0);
                bias = float4(0);
            }
        }
    }
    _output = half4(float(t) * scale + bias);
    return _output;
}
half4 ClampedGradientEffect_Stage1_c0_c0(half4 _input)
{
    half4 _output;
    half4 t = MatrixEffect_Stage1_c0_c0_c0(_input);
    if (!false && t.y < 0.0)
    {
        _output = half4(0.0);
    }
    else if (t.x < 0.0)
    {
        _output = uleftBorderColor_Stage1_c0_c0;
    }
    else if (t.x > 1.0)
    {
        _output = urightBorderColor_Stage1_c0_c0;
    }
    else
    {
        _output = UnrolledBinaryGradientColorizer_Stage1_c0_c0_c1(_input, float2(half2(t.x, 0.0)));
    }
    @if (false)
    {
        _output.xyz *= _output.w;
    }
    return _output;
}
half4 OverrideInputFragmentProcessor_Stage1_c0(half4 _input)
{
    half4 _output;
    half4 constColor;
    @if (false)
    {
        constColor = half4(0);
    }
    else
    {
        constColor = half4(1.000000, 1.000000, 1.000000, 1.000000);
    }
    _output = ClampedGradientEffect_Stage1_c0_c0(constColor);
    return _output;
}
void main()
{
    half4 outputColor_Stage0;
    half4 outputCoverage_Stage0;
    {
        // Stage 0, QuadPerEdgeAAGeometryProcessor
        outputColor_Stage0 = vcolor_Stage0;
        float coverage = vcoverage_Stage0 * sk_FragCoord.w;
        float4 geoSubset;
        geoSubset = vgeomSubset_Stage0;
        if (coverage < 0.5)
        {
            float4 dists4 = clamp(float4(1, 1, -1, -1) * (sk_FragCoord.xyxy - geoSubset), 0, 1);
            float2 dists2 = dists4.xy * dists4.zw;
            coverage = min(coverage, dists2.x * dists2.y);
        }
        outputCoverage_Stage0 = half4(half(coverage));
    }
    half4 output_Stage1;
    {
        // Stage 1, DitherEffect
        half4 color = OverrideInputFragmentProcessor_Stage1_c0(outputColor_Stage0);
        half value;
        @if (sk_Caps.integerSupport)
        {
            uint x = uint(sk_FragCoord.x);
            uint y = uint(sk_FragCoord.y) ^ x;
            uint m = (((((y & 1) << 5 | (x & 1) << 4) | (y & 2) << 2) | (x & 2) << 1) | (y & 4) >> 1) | (x & 4) >> 2;
            value = half(m) / 64.0 - 0.4921875;
        }
        else
        {
            half4 bits = mod(half4(sk_FragCoord.yxyx), half4(2.0, 2.0, 4.0, 4.0));
            bits.zw = step(2.0, bits.zw);
            bits.xz = abs(bits.xz - bits.yw);
            value = dot(bits, half4(0.5, 0.25, 0.125, 0.0625)) - 0.46875;
        }
        output_Stage1 = half4(clamp(color.xyz + value * urange_Stage1, 0.0, color.w), color.w);
    }
    {
        // Xfer Processor: Porter Duff
        sk_FragColor = output_Stage1 * outputCoverage_Stage0;
    }
}
)");)

DEF_BENCH(return new SkSLBench("medium", R"(
    uniform half2 uDstTextureUpperLeft_Stage1;
    uniform half2 uDstTextureCoordScale_Stage1;
    uniform sampler2D uDstTextureSampler_Stage1;
    noperspective in half4 vQuadEdge_Stage0;
    noperspective in half4 vinColor_Stage0;
    out half4 sk_FragColor;
    half luminance_Stage1(half3 color) {
        return dot(half3(0.3, 0.59, 0.11), color);
    }

    half3 set_luminance_Stage1(half3 hueSat, half alpha, half3 lumColor) {
        half diff = luminance_Stage1(lumColor - hueSat);
        half3 outColor = hueSat + diff;
        half outLum = luminance_Stage1(outColor);
        half minComp = min(min(outColor.r, outColor.g), outColor.b);
        half maxComp = max(max(outColor.r, outColor.g), outColor.b);
        if (minComp < 0.0 && outLum != minComp) {
            outColor = outLum + ((outColor - half3(outLum, outLum, outLum)) * outLum) /
                       (outLum - minComp);
        }
        if (maxComp > alpha && maxComp != outLum) {
            outColor = outLum +((outColor - half3(outLum, outLum, outLum)) * (alpha - outLum)) /
                       (maxComp - outLum);
        }
        return outColor;
    }

    void main() {
        half4 outputColor_Stage0;
        half4 outputCoverage_Stage0;
        { // Stage 0, QuadEdge
            outputColor_Stage0 = vinColor_Stage0;
            half edgeAlpha;
            half2 duvdx = half2(dFdx(vQuadEdge_Stage0.xy));
            half2 duvdy = half2(dFdy(vQuadEdge_Stage0.xy));
            if (vQuadEdge_Stage0.z > 0.0 && vQuadEdge_Stage0.w > 0.0) {
                edgeAlpha = min(min(vQuadEdge_Stage0.z, vQuadEdge_Stage0.w) + 0.5, 1.0);
            } else {
                half2 gF = half2(2.0 * vQuadEdge_Stage0.x * duvdx.x - duvdx.y,
                                 2.0 * vQuadEdge_Stage0.x * duvdy.x - duvdy.y);
                edgeAlpha = (vQuadEdge_Stage0.x*vQuadEdge_Stage0.x - vQuadEdge_Stage0.y);
                edgeAlpha = saturate(0.5 - edgeAlpha / length(gF));
            }
            outputCoverage_Stage0 = half4(edgeAlpha);
        }
        { // Xfer Processor: Custom Xfermode
            if (all(lessThanEqual(outputCoverage_Stage0.rgb, half3(0)))) {
                discard;
            }
            // Read color from copy of the destination.
            half2 _dstTexCoord = (half2(sk_FragCoord.xy) - uDstTextureUpperLeft_Stage1) *
                                  uDstTextureCoordScale_Stage1;
            _dstTexCoord.y = 1.0 - _dstTexCoord.y;
            half4 _dstColor = sample(uDstTextureSampler_Stage1, _dstTexCoord);
            sk_FragColor.a = outputColor_Stage0.a + (1.0 - outputColor_Stage0.a) * _dstColor.a;
            half4 srcDstAlpha = outputColor_Stage0 * _dstColor.a;
            sk_FragColor.rgb = set_luminance_Stage1(_dstColor.rgb * outputColor_Stage0.a,
                                                    srcDstAlpha.a, srcDstAlpha.rgb);
            sk_FragColor.rgb += (1.0 - outputColor_Stage0.a) * _dstColor.rgb + (1.0 - _dstColor.a) *
                                outputColor_Stage0.rgb;
            sk_FragColor = outputCoverage_Stage0 * sk_FragColor +
                           (half4(1.0) - outputCoverage_Stage0) * _dstColor;
        }
    }
)"); )

#if defined(SK_BUILD_FOR_UNIX)

#include <malloc.h>

// These benchmarks aren't timed, they produce memory usage statistics. They run standalone, and
// directly add their results to the nanobench log.
void RunSkSLMemoryBenchmarks(NanoJSONResultsWriter* log) {
    auto heap_bytes_used = []() { return mallinfo().uordblks; };
    auto bench = [log](const char* name, int bytes) {
        log->beginObject(name);          // test
        log->beginObject("meta");        //   config
        log->appendS32("bytes", bytes);  //     sub_result
        log->endObject();                //   config
        log->endObject();                // test
    };

    {
        int before = heap_bytes_used();
        SkSL::Compiler compiler;
        int after = heap_bytes_used();
        bench("sksl_compiler_baseline", after - before);
    }
}

#else

void RunSkSLMemoryBenchmarks(NanoJSONResultsWriter*) {}

#endif
