/*
 * 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 "include/core/SkCanvas.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/mock/GrMockCaps.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/SkSLModuleLoader.h"
#include "src/sksl/SkSLParser.h"
#include "src/sksl/codegen/SkSLVMCodeGenerator.h"
#include "src/sksl/ir/SkSLProgram.h"

#include <regex>

#include "src/sksl/generated/sksl_shared.minified.sksl"
#include "src/sksl/generated/sksl_compute.minified.sksl"
#include "src/sksl/generated/sksl_frag.minified.sksl"
#include "src/sksl/generated/sksl_gpu.minified.sksl"
#include "src/sksl/generated/sksl_public.minified.sksl"
#include "src/sksl/generated/sksl_rt_shader.minified.sksl"
#include "src/sksl/generated/sksl_vert.minified.sksl"
#if defined(SK_GRAPHITE)
#include "src/sksl/generated/sksl_graphite_frag.minified.sksl"
#include "src/sksl/generated/sksl_graphite_vert.minified.sksl"
#endif

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 {
        GrShaderCaps caps;
        for (int i = 0; i < loops; i++) {
            SkSL::Compiler compiler(&caps);
        }
    }
};

DEF_BENCH(return new SkSLCompilerStartupBench();)

enum class Output {
    kNone,
    kGLSL,
    kMetal,
    kSPIRV,
    kSkVM,     // raw SkVM bytecode
    kSkVMOpt,  // optimized SkVM bytecode
    kSkVMJIT,  // optimized native assembly code
};

class SkSLCompileBench : public Benchmark {
public:
    static const char* output_string(Output output) {
        switch (output) {
            case Output::kNone:    return "";
            case Output::kGLSL:    return "glsl_";
            case Output::kMetal:   return "metal_";
            case Output::kSPIRV:   return "spirv_";
            case Output::kSkVM:    return "skvm_";
            case Output::kSkVMOpt: return "skvm_opt_";
            case Output::kSkVMJIT: return "skvm_jit_";
        }
        SkUNREACHABLE;
    }

    SkSLCompileBench(std::string name, const char* src, bool optimize, Output output)
            : fName(std::string("sksl_") + (optimize ? "" : "unoptimized_") +
                    output_string(output) + name)
            , fSrc(src)
            , fCaps(GrContextOptions(), GrMockOptions())
            , fCompiler(fCaps.shaderCaps())
            , fOutput(output) {
        fSettings.fOptimize = optimize;
        // The test programs we compile don't follow Vulkan rules and thus produce invalid SPIR-V.
        // This is harmless, so long as we don't try to validate them.
        fSettings.fValidateSPIRV = false;

        this->fixUpSource();
    }

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

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

    bool usesRuntimeShader() const {
        return fOutput >= Output::kSkVM;
    }

    void fixUpSource() {
        auto fixup = [this](const char* input, const char* replacement) {
            fSrc = std::regex_replace(fSrc, std::regex(input), replacement);
        };

        // Runtime shaders which have slightly different conventions than fragment shaders.
        // Perform a handful of fixups to compensate. These are hand-tuned for our current set of
        // test shaders and will probably need to be updated if we add more.
        if (this->usesRuntimeShader()) {
            fixup(R"(void main\(\))",                              "half4 main(float2 xy)");
            fixup(R"(sk_FragColor =)",                             "return");
            fixup(R"(sk_FragCoord)",                               "_FragCoord");
            fixup(R"(uniform sampler2D )",                         "uniform shader ");
            fixup(R"((flat |noperspective |)in )",                 "uniform ");
            fixup(R"(sample\(([A-Za-z0-9_]+), ([A-Za-z0-9_]+)\))", "$01.eval($02)");
            fSrc = "#version 300\nuniform float4 _FragCoord;\n" + fSrc;
        }
    }

    void onDraw(int loops, SkCanvas* canvas) override {
        const SkSL::ProgramKind kind = this->usesRuntimeShader() ? SkSL::ProgramKind::kRuntimeShader
                                                                 : SkSL::ProgramKind::kFragment;
        for (int i = 0; i < loops; i++) {
            std::unique_ptr<SkSL::Program> program = fCompiler.convertProgram(kind, fSrc,
                                                                              fSettings);
            if (fCompiler.errorCount()) {
                SK_ABORT("shader compilation failed: %s\n", fCompiler.errorText().c_str());
            }
            std::string result;
            switch (fOutput) {
                case Output::kNone:    break;
                case Output::kGLSL:    SkAssertResult(fCompiler.toGLSL(*program,  &result)); break;
                case Output::kMetal:   SkAssertResult(fCompiler.toMetal(*program, &result)); break;
                case Output::kSPIRV:   SkAssertResult(fCompiler.toSPIRV(*program, &result)); break;
                case Output::kSkVM:
                case Output::kSkVMOpt:
                case Output::kSkVMJIT: SkAssertResult(CompileToSkVM(*program, fOutput)); break;
            }
        }
    }

    static bool CompileToSkVM(const SkSL::Program& program, Output mode) {
        const bool optimize = (mode >= Output::kSkVMOpt);
        const bool allowJIT = (mode >= Output::kSkVMJIT);
        skvm::Builder builder{skvm::Features{}};
        if (!SkSL::testingOnly_ProgramToSkVMShader(program, &builder, /*debugTrace=*/nullptr)) {
            return false;
        }
        if (optimize) {
            builder.done("SkSLBench", allowJIT);
        }
        return true;
    }

private:
    std::string fName;
    std::string fSrc;
    GrMockCaps fCaps;
    SkSL::Compiler fCompiler;
    SkSL::ProgramSettings fSettings;
    Output fOutput;

    using INHERITED = Benchmark;
};

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

#define COMPILER_BENCH(name, text)                                                                 \
static constexpr char name ## _SRC[] = text;                                                       \
DEF_BENCH(return new SkSLCompileBench(#name, name ## _SRC, /*optimize=*/false, Output::kNone);)    \
DEF_BENCH(return new SkSLCompileBench(#name, name ## _SRC, /*optimize=*/true,  Output::kNone);)    \
DEF_BENCH(return new SkSLCompileBench(#name, name ## _SRC, /*optimize=*/true,  Output::kGLSL);)    \
DEF_BENCH(return new SkSLCompileBench(#name, name ## _SRC, /*optimize=*/true,  Output::kMetal);)   \
DEF_BENCH(return new SkSLCompileBench(#name, name ## _SRC, /*optimize=*/true,  Output::kSPIRV);)   \
DEF_BENCH(return new SkSLCompileBench(#name, name ## _SRC, /*optimize=*/true,  Output::kSkVM);)    \
DEF_BENCH(return new SkSLCompileBench(#name, name ## _SRC, /*optimize=*/true,  Output::kSkVMOpt);) \
DEF_BENCH(return new SkSLCompileBench(#name, name ## _SRC, /*optimize=*/true,  Output::kSkVMJIT);)

// This fragment shader is from the third tile on the top row of GM_gradients_2pt_conical_outside.
// To get an ES2 compatible shader, nonconstantArrayIndexSupport in GrShaderCaps is forced off.
COMPILER_BENCH(large, R"(
uniform float3x3 umatrix_S1_c0;
uniform half4 uthresholds1_7_S1_c1_c0_c0;
uniform half4 uthresholds9_13_S1_c1_c0_c0;
uniform float4 uscale_S1_c1_c0_c0[4];
uniform float4 ubias_S1_c1_c0_c0[4];
uniform half uinvR1_S1_c1_c0_c1_c0;
uniform half ufx_S1_c1_c0_c1_c0;
uniform float3x3 umatrix_S1_c1_c0_c1;
uniform half4 uleftBorderColor_S1_c1_c0;
uniform half4 urightBorderColor_S1_c1_c0;
uniform half urange_S1;
uniform sampler2D uTextureSampler_0_S1;
flat in half4 vcolor_S0;
noperspective in float2 vTransformedCoords_8_S0;
half4 TextureEffect_S1_c0_c0(half4 _input, float2 _coords)
{
	return sample(uTextureSampler_0_S1, _coords).000r;
}
half4 MatrixEffect_S1_c0(half4 _input, float2 _coords)
{
	return TextureEffect_S1_c0_c0(_input, float3x2(umatrix_S1_c0) * _coords.xy1);
}
half4 UnrolledBinaryColorizer_S1_c1_c0_c0(half4 _input, float2 _coords)
{
	half4 _tmp_0_inColor = _input;
	float2 _tmp_1_coords = _coords;
	half t = half(_tmp_1_coords.x);
	float4 s;
	float4 b;
	{
		if (t < uthresholds1_7_S1_c1_c0_c0.y)
		{
			if (t < uthresholds1_7_S1_c1_c0_c0.x)
			{
				s = uscale_S1_c1_c0_c0[0];
				b = ubias_S1_c1_c0_c0[0];
			}
			else
			{
				s = uscale_S1_c1_c0_c0[1];
				b = ubias_S1_c1_c0_c0[1];
			}
		}
		else
		{
			if (t < uthresholds1_7_S1_c1_c0_c0.z)
			{
				s = uscale_S1_c1_c0_c0[2];
				b = ubias_S1_c1_c0_c0[2];
			}
			else
			{
				s = uscale_S1_c1_c0_c0[3];
				b = ubias_S1_c1_c0_c0[3];
			}
		}
	}
	return half4(half4(float(t) * s + b));
}
half4 TwoPointConicalFocalLayout_S1_c1_c0_c1_c0(half4 _input)
{
	half4 _tmp_2_inColor = _input;
	float2 _tmp_3_coords = vTransformedCoords_8_S0;
	float t = -1.0;
	half v = 1.0;
	float x_t = -1.0;
	if (bool(int(0)))
	{
		x_t = dot(_tmp_3_coords, _tmp_3_coords) / _tmp_3_coords.x;
	}
	else if (bool(int(0)))
	{
		x_t = length(_tmp_3_coords) - _tmp_3_coords.x * float(uinvR1_S1_c1_c0_c1_c0);
	}
	else
	{
		float temp = _tmp_3_coords.x * _tmp_3_coords.x - _tmp_3_coords.y * _tmp_3_coords.y;
		if (temp >= 0.0)
		{
			if (bool(int(0)) || !bool(int(1)))
			{
				x_t = -sqrt(temp) - _tmp_3_coords.x * float(uinvR1_S1_c1_c0_c1_c0);
			}
			else
			{
				x_t = sqrt(temp) - _tmp_3_coords.x * float(uinvR1_S1_c1_c0_c1_c0);
			}
		}
	}
	if (!bool(int(0)))
	{
		if (x_t <= 0.0)
		{
			v = -1.0;
		}
	}
	if (bool(int(1)))
	{
		if (bool(int(0)))
		{
			t = x_t;
		}
		else
		{
			t = x_t + float(ufx_S1_c1_c0_c1_c0);
		}
	}
	else
	{
		if (bool(int(0)))
		{
			t = -x_t;
		}
		else
		{
			t = -x_t + float(ufx_S1_c1_c0_c1_c0);
		}
	}
	if (bool(int(0)))
	{
		t = 1.0 - t;
	}
	return half4(half4(half(t), v, 0.0, 0.0));
}
half4 MatrixEffect_S1_c1_c0_c1(half4 _input)
{
	return TwoPointConicalFocalLayout_S1_c1_c0_c1_c0(_input);
}
half4 ClampedGradient_S1_c1_c0(half4 _input)
{
	half4 _tmp_4_inColor = _input;
	half4 t = MatrixEffect_S1_c1_c0_c1(_tmp_4_inColor);
	half4 outColor;
	if (!bool(int(0)) && t.y < 0.0)
	{
		outColor = half4(0.0);
	}
	else if (t.x < 0.0)
	{
		outColor = uleftBorderColor_S1_c1_c0;
	}
	else if (t.x > 1.0)
	{
		outColor = urightBorderColor_S1_c1_c0;
	}
	else
	{
		outColor = UnrolledBinaryColorizer_S1_c1_c0_c0(_tmp_4_inColor, float2(half2(t.x, 0.0)));
	}
	if (bool(int(0)))
	{
		outColor.xyz *= outColor.w;
	}
	return half4(outColor);
}
half4 DisableCoverageAsAlpha_S1_c1(half4 _input)
{
	_input = ClampedGradient_S1_c1_c0(_input);
	half4 _tmp_5_inColor = _input;
	return half4(_input);
}
half4 Dither_S1(half4 _input)
{
	_input = DisableCoverageAsAlpha_S1_c1(_input);
	half4 _tmp_6_inColor = _input;
	half value = MatrixEffect_S1_c0(_tmp_6_inColor, sk_FragCoord.xy).w - 0.5;
	return half4(half4(clamp(_input.xyz + value * urange_S1, 0.0, _input.w), _input.w));
}
void main()
{
	// Stage 0, QuadPerEdgeAAGeometryProcessor
	half4 outputColor_S0;
	outputColor_S0 = vcolor_S0;
	const half4 outputCoverage_S0 = half4(1);
	half4 output_S1;
	output_S1 = Dither_S1(outputColor_S0);
	{
		// Xfer Processor: Porter Duff
		sk_FragColor = output_S1 * outputCoverage_S0;
	}
}
)");

// This fragment shader is taken from GM_BlurDrawImage.
COMPILER_BENCH(medium, R"(
uniform float3x3 umatrix_S1_c0;
uniform float3x3 umatrix_S2_c0_c0;
uniform float4 urect_S2_c0;
uniform sampler2D uTextureSampler_0_S1;
uniform sampler2D uTextureSampler_0_S2;
flat in half4 vcolor_S0;
noperspective in float2 vTransformedCoords_3_S0;
half4 TextureEffect_S1_c0_c0(half4 _input)
{
	return sample(uTextureSampler_0_S1, vTransformedCoords_3_S0);
}
half4 MatrixEffect_S1_c0(half4 _input)
{
	return TextureEffect_S1_c0_c0(_input);
}
half4 DisableCoverageAsAlpha_S1(half4 _input)
{
	_input = MatrixEffect_S1_c0(_input);
	half4 _tmp_0_inColor = _input;
	return half4(_input);
}
half4 TextureEffect_S2_c0_c0_c0(half4 _input, float2 _coords)
{
	return sample(uTextureSampler_0_S2, _coords).000r;
}
half4 MatrixEffect_S2_c0_c0(half4 _input, float2 _coords)
{
	return TextureEffect_S2_c0_c0_c0(_input, float3x2(umatrix_S2_c0_c0) * _coords.xy1);
}
half4 RectBlur_S2_c0(half4 _input, float2 _coords)
{
	half4 _tmp_1_inColor = _input;
	float2 _tmp_2_coords = _coords;
	half xCoverage;
	half yCoverage;
	if (bool(int(1)))
	{
		half2 xy = max(half2(urect_S2_c0.xy - _tmp_2_coords), half2(_tmp_2_coords - urect_S2_c0.zw));
		xCoverage = MatrixEffect_S2_c0_c0(_tmp_1_inColor, float2(half2(xy.x, 0.5))).w;
		yCoverage = MatrixEffect_S2_c0_c0(_tmp_1_inColor, float2(half2(xy.y, 0.5))).w;
	}
	else
	{
		half4 rect = half4(half2(urect_S2_c0.xy - _tmp_2_coords), half2(_tmp_2_coords - urect_S2_c0.zw));
		xCoverage = (1.0 - MatrixEffect_S2_c0_c0(_tmp_1_inColor, float2(half2(rect.x, 0.5))).w) - MatrixEffect_S2_c0_c0(_tmp_1_inColor, float2(half2(rect.z, 0.5))).w;
		yCoverage = (1.0 - MatrixEffect_S2_c0_c0(_tmp_1_inColor, float2(half2(rect.y, 0.5))).w) - MatrixEffect_S2_c0_c0(_tmp_1_inColor, float2(half2(rect.w, 0.5))).w;
	}
	return half4((_input * xCoverage) * yCoverage);
}
half4 DeviceSpace_S2(half4 _input)
{
	return RectBlur_S2_c0(_input, sk_FragCoord.xy);
}
void main()
{
	// Stage 0, QuadPerEdgeAAGeometryProcessor
	half4 outputColor_S0;
	outputColor_S0 = vcolor_S0;
	const half4 outputCoverage_S0 = half4(1);
	half4 output_S1;
	output_S1 = DisableCoverageAsAlpha_S1(outputColor_S0);
	half4 output_S2;
	output_S2 = DeviceSpace_S2(outputCoverage_S0);
	{
		// Xfer Processor: Porter Duff
		sk_FragColor = output_S1 * output_S2;
	}
}
)");

// This fragment shader is taken from GM_lcdtext.
COMPILER_BENCH(small, R"(
uniform sampler2D uTextureSampler_0_S0;
noperspective in float2 vTextureCoords_S0;
flat in float vTexIndex_S0;
noperspective in half4 vinColor_S0;
void main()
{
	// Stage 0, BitmapText
	half4 outputColor_S0;
	outputColor_S0 = vinColor_S0;
	half4 texColor;
	{
		texColor = sample(uTextureSampler_0_S0, vTextureCoords_S0).rrrr;
	}
	half4 outputCoverage_S0 = texColor;
	{
		// Xfer Processor: Porter Duff
		sk_FragColor = outputColor_S0 * outputCoverage_S0;
	}
}
)");

COMPILER_BENCH(tiny, "void main() { sk_FragColor = half4(1); }");

#if defined(SK_BUILD_FOR_UNIX)

#include <malloc.h>
static int64_t heap_bytes_used() {
    return (int64_t)mallinfo().uordblks;
}

#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)

#include <malloc/malloc.h>
static int64_t heap_bytes_used() {
    malloc_statistics_t stats;
    malloc_zone_pressure_relief(malloc_default_zone(), 0);
    malloc_zone_statistics(malloc_default_zone(), &stats);
    return (int64_t)stats.size_in_use;
}

#else

static int64_t heap_bytes_used() {
    return -1;
}

#endif

static void bench(NanoJSONResultsWriter* log, const char* name, int bytes) {
    SkDEBUGCODE(SkDebugf("%s: %d bytes\n", name, bytes);)
    log->beginObject(name);          // test
    log->beginObject("meta");        //   config
    log->appendS32("bytes", bytes);  //     sub_result
    log->endObject();                //   config
    log->endObject();                // test
}

// These benchmarks aren't timed, they produce memory usage statistics. They run standalone, and
// directly add their results to the nanobench log.
void RunSkSLModuleBenchmarks(NanoJSONResultsWriter* log) {
    // Heap used by a default compiler (with no modules loaded)
    int64_t before = heap_bytes_used();
    GrShaderCaps caps;
    SkSL::Compiler compiler(&caps);
    int baselineBytes = heap_bytes_used();
    if (baselineBytes >= 0) {
        baselineBytes = (baselineBytes - before);
        bench(log, "sksl_compiler_baseline", baselineBytes);
    }

    // Heap used by a compiler with the two main GPU modules (fragment + vertex) and runtime effects
    // (shader + color filter + blender) loaded. Ganesh will load all of these in regular usage.
    before = heap_bytes_used();
    compiler.moduleForProgramKind(SkSL::ProgramKind::kVertex);
    compiler.moduleForProgramKind(SkSL::ProgramKind::kFragment);
    compiler.moduleForProgramKind(SkSL::ProgramKind::kRuntimeColorFilter);
    compiler.moduleForProgramKind(SkSL::ProgramKind::kRuntimeShader);
    compiler.moduleForProgramKind(SkSL::ProgramKind::kRuntimeBlender);
    compiler.moduleForProgramKind(SkSL::ProgramKind::kPrivateRuntimeColorFilter);
    compiler.moduleForProgramKind(SkSL::ProgramKind::kPrivateRuntimeShader);
    compiler.moduleForProgramKind(SkSL::ProgramKind::kPrivateRuntimeBlender);
    int64_t gpuBytes = heap_bytes_used();
    if (gpuBytes >= 0) {
        gpuBytes = (gpuBytes - before) + baselineBytes;
        bench(log, "sksl_compiler_gpu", gpuBytes);
    }

#if defined(SK_GRAPHITE)
    // Heap used by a compiler with the Graphite modules loaded.
    before = heap_bytes_used();
    compiler.moduleForProgramKind(SkSL::ProgramKind::kGraphiteVertex);
    compiler.moduleForProgramKind(SkSL::ProgramKind::kGraphiteFragment);
    int64_t graphiteBytes = heap_bytes_used();
    if (graphiteBytes >= 0) {
        graphiteBytes = (graphiteBytes - before) + gpuBytes;
        bench(log, "sksl_compiler_graphite", graphiteBytes);
    }
#endif

    // Heap used by a compiler with compute-shader support loaded.
    before = heap_bytes_used();
    compiler.moduleForProgramKind(SkSL::ProgramKind::kCompute);
    int64_t computeBytes = heap_bytes_used();
    if (computeBytes >= 0) {
        computeBytes = (computeBytes - before) + baselineBytes;
        bench(log, "sksl_compiler_compute", computeBytes);
    }

    // Report the minified module sizes.
    int compilerGPUBinarySize = std::size(SKSL_MINIFIED_sksl_shared) +
                                std::size(SKSL_MINIFIED_sksl_gpu) +
                                std::size(SKSL_MINIFIED_sksl_vert) +
                                std::size(SKSL_MINIFIED_sksl_frag) +
                                std::size(SKSL_MINIFIED_sksl_public) +
                                std::size(SKSL_MINIFIED_sksl_rt_shader);
    bench(log, "sksl_binary_size_gpu", compilerGPUBinarySize);

#if defined(SK_GRAPHITE)
    int compilerGraphiteBinarySize = std::size(SKSL_MINIFIED_sksl_graphite_frag) +
                                     std::size(SKSL_MINIFIED_sksl_graphite_vert);
    bench(log, "sksl_binary_size_graphite", compilerGraphiteBinarySize);
#endif

    int compilerComputeBinarySize = std::size(SKSL_MINIFIED_sksl_compute);
    bench(log, "sksl_binary_size_compute", compilerComputeBinarySize);
}

class SkSLModuleLoaderBench : public Benchmark {
public:
    SkSLModuleLoaderBench(const char* name, std::vector<SkSL::ProgramKind> moduleList)
            : fName(name), fModuleList(std::move(moduleList)) {}

    const char* onGetName() override {
        return fName;
    }

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

    int calculateLoops(int defaultLoops) const override {
        return 1;
    }

    void onPreDraw(SkCanvas*) override {
        SkSL::ModuleLoader::Get().unloadModules();
    }

    void onDraw(int loops, SkCanvas*) override {
        SkASSERT(loops == 1);
        GrShaderCaps caps;
        SkSL::Compiler compiler(&caps);
        for (SkSL::ProgramKind kind : fModuleList) {
            compiler.moduleForProgramKind(kind);
        }
    }

    const char* fName;
    std::vector<SkSL::ProgramKind> fModuleList;
};

DEF_BENCH(return new SkSLModuleLoaderBench("sksl_module_loader_ganesh",
                                           {
                                                   SkSL::ProgramKind::kVertex,
                                                   SkSL::ProgramKind::kFragment,
                                                   SkSL::ProgramKind::kRuntimeColorFilter,
                                                   SkSL::ProgramKind::kRuntimeShader,
                                                   SkSL::ProgramKind::kRuntimeBlender,
                                                   SkSL::ProgramKind::kPrivateRuntimeColorFilter,
                                                   SkSL::ProgramKind::kPrivateRuntimeShader,
                                                   SkSL::ProgramKind::kPrivateRuntimeBlender,
                                                   SkSL::ProgramKind::kCompute,
                                           });)

DEF_BENCH(return new SkSLModuleLoaderBench("sksl_module_loader_graphite",
                                           {
                                                   SkSL::ProgramKind::kVertex,
                                                   SkSL::ProgramKind::kFragment,
                                                   SkSL::ProgramKind::kRuntimeColorFilter,
                                                   SkSL::ProgramKind::kRuntimeShader,
                                                   SkSL::ProgramKind::kRuntimeBlender,
                                                   SkSL::ProgramKind::kPrivateRuntimeColorFilter,
                                                   SkSL::ProgramKind::kPrivateRuntimeShader,
                                                   SkSL::ProgramKind::kPrivateRuntimeBlender,
                                                   SkSL::ProgramKind::kCompute,
                                                   SkSL::ProgramKind::kGraphiteVertex,
                                                   SkSL::ProgramKind::kGraphiteFragment,
                                           });)
