blob: 22afd284589be8045efcbb2dc4dd6e730b3249c0 [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
Nathaniel Nifong60c37e72019-10-16 11:21:47 -040013// 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 {
34 SkSL::Compiler compiler;
35 SkSL::Program::Settings settings;
36 auto program = compiler.convertProgram(SkSL::Program::kGeneric_Kind, fSrc, settings);
37 SkASSERT(compiler.errorCount() == 0);
Brian Osmanb08cc022020-04-02 11:38:40 -040038 fByteCode = compiler.toByteCode(*program);
Brian Osman569f12f2019-06-13 11:23:57 -040039 SkASSERT(compiler.errorCount() == 0);
Brian Osmanb08cc022020-04-02 11:38:40 -040040 fMain = fByteCode->getFunction("main");
Brian Osman569f12f2019-06-13 11:23:57 -040041
42 SkRandom rnd;
Brian Osman08a84962019-06-14 10:17:16 -040043 fPixels.resize(fCount * 4);
44 for (float& c : fPixels) {
45 c = rnd.nextF();
Brian Osman569f12f2019-06-13 11:23:57 -040046 }
47 }
48
49 void onDraw(int loops, SkCanvas*) override {
50 for (int i = 0; i < loops; i++) {
Brian Osmanb23d66e2019-09-27 10:25:57 -040051 float* args[] = {
52 fPixels.data() + 0 * fCount,
53 fPixels.data() + 1 * fCount,
54 fPixels.data() + 2 * fCount,
55 fPixels.data() + 3 * fCount,
56 };
Brian Osman2b1a5442019-06-19 11:40:33 -040057
Brian Osmanb08cc022020-04-02 11:38:40 -040058 SkAssertResult(fByteCode->runStriped(fMain, fCount, args, 4, nullptr, 0, nullptr, 0));
Brian Osman569f12f2019-06-13 11:23:57 -040059 }
60 }
61
62private:
63 SkString fName;
64 SkSL::String fSrc;
Brian Osmanb08cc022020-04-02 11:38:40 -040065 std::unique_ptr<SkSL::ByteCode> fByteCode;
Brian Osman569f12f2019-06-13 11:23:57 -040066 const SkSL::ByteCodeFunction* fMain;
67
68 int fCount;
Brian Osman08a84962019-06-14 10:17:16 -040069 std::vector<float> fPixels;
Brian Osman569f12f2019-06-13 11:23:57 -040070
71 typedef Benchmark INHERITED;
72};
73
74///////////////////////////////////////////////////////////////////////////////
75
Brian Osman2b1a5442019-06-19 11:40:33 -040076const char* kLumaToAlphaSrc = R"(
Brian Osman569f12f2019-06-13 11:23:57 -040077 void main(inout float4 color) {
78 color.a = color.r*0.3 + color.g*0.6 + color.b*0.1;
79 color.r = 0;
80 color.g = 0;
81 color.b = 0;
82 }
Brian Osman2b1a5442019-06-19 11:40:33 -040083)";
Brian Osman569f12f2019-06-13 11:23:57 -040084
Brian Osman2b1a5442019-06-19 11:40:33 -040085const char* kHighContrastFilterSrc = R"(
Brian Osman569f12f2019-06-13 11:23:57 -040086 half ucontrast_Stage2;
87 half hue2rgb_Stage2(half p, half q, half t) {
88 if (t < 0) t += 1;
89 if (t > 1) t -= 1;
Brian Osman4a47da72019-07-12 11:30:32 -040090 return (t < 1 / 6.) ? p + (q - p) * 6 * t
91 : (t < 1 / 2.) ? q
92 : (t < 2 / 3.) ? p + (q - p) * (2 / 3. - t) * 6
93 : p;
Brian Osman569f12f2019-06-13 11:23:57 -040094 }
95 half max(half a, half b) { return a > b ? a : b; }
96 half min(half a, half b) { return a < b ? a : b; }
97 void main(inout half4 color) {
98 ucontrast_Stage2 = 0.2;
99
100 // HighContrastFilter
101 half nonZeroAlpha = max(color.a, 0.0001);
102 color = half4(color.rgb / nonZeroAlpha, nonZeroAlpha);
103 color.rgb = color.rgb * color.rgb;
104 half fmax = max(color.r, max(color.g, color.b));
105 half fmin = min(color.r, min(color.g, color.b));
106 half l = (fmax + fmin) / 2;
107 half h;
108 half s;
109 if (fmax == fmin) {
110 h = 0;
111 s = 0;
112 } else {
113 half d = fmax - fmin;
114 s = l > 0.5 ? d / (2 - fmax - fmin) : d / (fmax + fmin);
115 if (color.r >= color.g && color.r >= color.b) {
116 h = (color.g - color.b) / d + (color.g < color.b ? 6 : 0);
117 } else if (color.g >= color.b) {
118 h = (color.b - color.r) / d + 2;
119 } else {
120 h = (color.r - color.g) / d + 4;
121 }
122 }
123 h /= 6;
124 l = 1.0 - l;
125 if (s == 0) {
126 color = half4(l, l, l, 0);
127 } else {
128 half q = l < 0.5 ? l * (1 + s) : l + s - l * s;
129 half p = 2 * l - q;
130 color.r = hue2rgb_Stage2(p, q, h + 1 / 3.);
131 color.g = hue2rgb_Stage2(p, q, h);
132 color.b = hue2rgb_Stage2(p, q, h - 1 / 3.);
133 }
134 if (ucontrast_Stage2 != 0) {
135 half m = (1 + ucontrast_Stage2) / (1 - ucontrast_Stage2);
136 half off = (-0.5 * m + 0.5);
137 color = m * color + off;
138 }
139 // color = saturate(color);
140 color.rgb = sqrt(color.rgb);
141 color.rgb *= color.a;
142 }
Brian Osman2b1a5442019-06-19 11:40:33 -0400143)";
144
Brian Osmanb23d66e2019-09-27 10:25:57 -0400145DEF_BENCH(return new SkSLInterpreterCFBench("lumaToAlpha", 256, kLumaToAlphaSrc));
146DEF_BENCH(return new SkSLInterpreterCFBench("hcf", 256, kHighContrastFilterSrc));
Nathaniel Nifong60c37e72019-10-16 11:21:47 -0400147#endif // SK_ENABLE_SKSL_INTERPRETER