blob: 2f9849b6a346761500cac6dda73339f5b54031e2 [file] [log] [blame]
Brian Osman569f12f2019-06-13 11:23:57 -04001/*
2 * Copyright 2019 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
Nathaniel Nifong60c37e72019-10-16 11:21:47 -04007
Brian Osman569f12f2019-06-13 11:23:57 -04008#include "bench/Benchmark.h"
9#include "include/utils/SkRandom.h"
Brian Osman08a84962019-06-14 10:17:16 -040010#include "src/sksl/SkSLByteCode.h"
Brian Osman569f12f2019-06-13 11:23:57 -040011#include "src/sksl/SkSLCompiler.h"
Brian Osman569f12f2019-06-13 11:23:57 -040012
Mike Klein853d4ed2020-08-20 00:41:00 +000013// Without this build flag, this bench isn't runnable.
14#if defined(SK_ENABLE_SKSL_INTERPRETER)
15
Brian Osman569f12f2019-06-13 11:23:57 -040016// Benchmarks the interpreter with a function that has a color-filter style signature
17class SkSLInterpreterCFBench : public Benchmark {
18public:
Brian Osmanb23d66e2019-09-27 10:25:57 -040019 SkSLInterpreterCFBench(SkSL::String name, int pixels, const char* src)
20 : fName(SkStringPrintf("sksl_interp_cf_%d_%s", pixels, name.c_str()))
Brian Osman569f12f2019-06-13 11:23:57 -040021 , fSrc(src)
Brian Osmanb23d66e2019-09-27 10:25:57 -040022 , fCount(pixels) {}
Brian Osman569f12f2019-06-13 11:23:57 -040023
24protected:
25 const char* onGetName() override {
26 return fName.c_str();
27 }
28
29 bool isSuitableFor(Backend backend) override {
30 return backend == kNonRendering_Backend;
31 }
32
33 void onDelayedSetup() override {
Brian Osman0006ad02020-11-18 15:38:39 -050034 GrShaderCaps caps(GrContextOptions{});
35 SkSL::Compiler compiler(&caps);
Brian Osman569f12f2019-06-13 11:23:57 -040036 SkSL::Program::Settings settings;
37 auto program = compiler.convertProgram(SkSL::Program::kGeneric_Kind, fSrc, settings);
38 SkASSERT(compiler.errorCount() == 0);
Brian Osmanb08cc022020-04-02 11:38:40 -040039 fByteCode = compiler.toByteCode(*program);
Brian Osman569f12f2019-06-13 11:23:57 -040040 SkASSERT(compiler.errorCount() == 0);
Brian Osmanb08cc022020-04-02 11:38:40 -040041 fMain = fByteCode->getFunction("main");
Brian Osman569f12f2019-06-13 11:23:57 -040042
43 SkRandom rnd;
Brian Osman08a84962019-06-14 10:17:16 -040044 fPixels.resize(fCount * 4);
45 for (float& c : fPixels) {
46 c = rnd.nextF();
Brian Osman569f12f2019-06-13 11:23:57 -040047 }
48 }
49
50 void onDraw(int loops, SkCanvas*) override {
51 for (int i = 0; i < loops; i++) {
Brian Osmanb23d66e2019-09-27 10:25:57 -040052 float* args[] = {
53 fPixels.data() + 0 * fCount,
54 fPixels.data() + 1 * fCount,
55 fPixels.data() + 2 * fCount,
56 fPixels.data() + 3 * fCount,
57 };
Brian Osman2b1a5442019-06-19 11:40:33 -040058
Brian Osmanb08cc022020-04-02 11:38:40 -040059 SkAssertResult(fByteCode->runStriped(fMain, fCount, args, 4, nullptr, 0, nullptr, 0));
Brian Osman569f12f2019-06-13 11:23:57 -040060 }
61 }
62
63private:
64 SkString fName;
65 SkSL::String fSrc;
Brian Osmanb08cc022020-04-02 11:38:40 -040066 std::unique_ptr<SkSL::ByteCode> fByteCode;
Brian Osman569f12f2019-06-13 11:23:57 -040067 const SkSL::ByteCodeFunction* fMain;
68
69 int fCount;
Brian Osman08a84962019-06-14 10:17:16 -040070 std::vector<float> fPixels;
Brian Osman569f12f2019-06-13 11:23:57 -040071
John Stiles7571f9e2020-09-02 22:42:33 -040072 using INHERITED = Benchmark;
Brian Osman569f12f2019-06-13 11:23:57 -040073};
74
75///////////////////////////////////////////////////////////////////////////////
76
Brian Osman2b1a5442019-06-19 11:40:33 -040077const char* kLumaToAlphaSrc = R"(
Brian Osman569f12f2019-06-13 11:23:57 -040078 void main(inout float4 color) {
79 color.a = color.r*0.3 + color.g*0.6 + color.b*0.1;
80 color.r = 0;
81 color.g = 0;
82 color.b = 0;
83 }
Brian Osman2b1a5442019-06-19 11:40:33 -040084)";
Brian Osman569f12f2019-06-13 11:23:57 -040085
Brian Osman2b1a5442019-06-19 11:40:33 -040086const char* kHighContrastFilterSrc = R"(
Brian Osman569f12f2019-06-13 11:23:57 -040087 half ucontrast_Stage2;
88 half hue2rgb_Stage2(half p, half q, half t) {
89 if (t < 0) t += 1;
90 if (t > 1) t -= 1;
Brian Osman4a47da72019-07-12 11:30:32 -040091 return (t < 1 / 6.) ? p + (q - p) * 6 * t
92 : (t < 1 / 2.) ? q
93 : (t < 2 / 3.) ? p + (q - p) * (2 / 3. - t) * 6
94 : p;
Brian Osman569f12f2019-06-13 11:23:57 -040095 }
96 half max(half a, half b) { return a > b ? a : b; }
97 half min(half a, half b) { return a < b ? a : b; }
98 void main(inout half4 color) {
99 ucontrast_Stage2 = 0.2;
100
101 // HighContrastFilter
102 half nonZeroAlpha = max(color.a, 0.0001);
103 color = half4(color.rgb / nonZeroAlpha, nonZeroAlpha);
104 color.rgb = color.rgb * color.rgb;
105 half fmax = max(color.r, max(color.g, color.b));
106 half fmin = min(color.r, min(color.g, color.b));
107 half l = (fmax + fmin) / 2;
108 half h;
109 half s;
110 if (fmax == fmin) {
111 h = 0;
112 s = 0;
113 } else {
114 half d = fmax - fmin;
115 s = l > 0.5 ? d / (2 - fmax - fmin) : d / (fmax + fmin);
116 if (color.r >= color.g && color.r >= color.b) {
117 h = (color.g - color.b) / d + (color.g < color.b ? 6 : 0);
118 } else if (color.g >= color.b) {
119 h = (color.b - color.r) / d + 2;
120 } else {
121 h = (color.r - color.g) / d + 4;
122 }
123 }
124 h /= 6;
125 l = 1.0 - l;
126 if (s == 0) {
127 color = half4(l, l, l, 0);
128 } else {
129 half q = l < 0.5 ? l * (1 + s) : l + s - l * s;
130 half p = 2 * l - q;
131 color.r = hue2rgb_Stage2(p, q, h + 1 / 3.);
132 color.g = hue2rgb_Stage2(p, q, h);
133 color.b = hue2rgb_Stage2(p, q, h - 1 / 3.);
134 }
135 if (ucontrast_Stage2 != 0) {
136 half m = (1 + ucontrast_Stage2) / (1 - ucontrast_Stage2);
137 half off = (-0.5 * m + 0.5);
138 color = m * color + off;
139 }
140 // color = saturate(color);
141 color.rgb = sqrt(color.rgb);
142 color.rgb *= color.a;
143 }
Brian Osman2b1a5442019-06-19 11:40:33 -0400144)";
145
Brian Osmanb23d66e2019-09-27 10:25:57 -0400146DEF_BENCH(return new SkSLInterpreterCFBench("lumaToAlpha", 256, kLumaToAlphaSrc));
147DEF_BENCH(return new SkSLInterpreterCFBench("hcf", 256, kHighContrastFilterSrc));
Mike Klein853d4ed2020-08-20 00:41:00 +0000148#endif // SK_ENABLE_SKSL_INTERPRETER