blob: 4175e395fcd038f5ce0a1f475140beb8d18fc340 [file] [log] [blame]
Ethan Nicholas40679c32019-05-31 17:06:53 -04001/*
Ethan Nicholasfc994162019-06-06 10:04:27 -04002 * Copyright 2019 Google LLC
Ethan Nicholas40679c32019-05-31 17:06:53 -04003 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7#include "bench/Benchmark.h"
Brian Osman68870aa2020-07-08 14:12:43 -04008#include "bench/ResultsWriter.h"
9#include "bench/SkSLBench.h"
Ethan Nicholas40679c32019-05-31 17:06:53 -040010#include "src/sksl/SkSLCompiler.h"
11
12class SkSLBench : public Benchmark {
13public:
14 SkSLBench(SkSL::String name, const char* src)
15 : fName("sksl_" + name)
16 , fSrc(src) {}
17
18protected:
19 const char* onGetName() override {
20 return fName.c_str();
21 }
22
23 bool isSuitableFor(Backend backend) override {
24 return backend == kNonRendering_Backend;
25 }
26
27 void onDraw(int loops, SkCanvas*) override {
28 for (int i = 0; i < loops; i++) {
29 std::unique_ptr<SkSL::Program> program = fCompiler.convertProgram(
30 SkSL::Program::kFragment_Kind,
31 fSrc,
32 fSettings);
33 if (!fCompiler.errorCount()) {
34 fCompiler.optimize(*program);
35 } else {
36 printf("%s\n", fCompiler.errorText().c_str());
37 SK_ABORT("shader compilation failed");
38 }
39 }
40 }
41
42private:
43 SkSL::String fName;
44 SkSL::String fSrc;
45 SkSL::Compiler fCompiler;
46 SkSL::Program::Settings fSettings;
47
48 typedef Benchmark INHERITED;
49};
50
51///////////////////////////////////////////////////////////////////////////////
52
53DEF_BENCH(return new SkSLBench("tiny", "void main() { sk_FragColor = half4(1); }"); )
54DEF_BENCH(return new SkSLBench("huge", R"(
55 uniform half2 uDstTextureUpperLeft_Stage1;
56 uniform half2 uDstTextureCoordScale_Stage1;
57 uniform sampler2D uDstTextureSampler_Stage1;
58 noperspective in half4 vQuadEdge_Stage0;
59 noperspective in half4 vinColor_Stage0;
60 out half4 sk_FragColor;
61 half luminance_Stage1(half3 color) {
62 return dot(half3(0.3, 0.59, 0.11), color);
63 }
64
65 half3 set_luminance_Stage1(half3 hueSat, half alpha, half3 lumColor) {
66 half diff = luminance_Stage1(lumColor - hueSat);
67 half3 outColor = hueSat + diff;
68 half outLum = luminance_Stage1(outColor);
69 half minComp = min(min(outColor.r, outColor.g), outColor.b);
70 half maxComp = max(max(outColor.r, outColor.g), outColor.b);
71 if (minComp < 0.0 && outLum != minComp) {
72 outColor = outLum + ((outColor - half3(outLum, outLum, outLum)) * outLum) /
73 (outLum - minComp);
74 }
75 if (maxComp > alpha && maxComp != outLum) {
76 outColor = outLum +((outColor - half3(outLum, outLum, outLum)) * (alpha - outLum)) /
77 (maxComp - outLum);
78 }
79 return outColor;
80 }
81
82 void main() {
83 half4 outputColor_Stage0;
84 half4 outputCoverage_Stage0;
85 { // Stage 0, QuadEdge
86 outputColor_Stage0 = vinColor_Stage0;
87 half edgeAlpha;
88 half2 duvdx = half2(dFdx(vQuadEdge_Stage0.xy));
89 half2 duvdy = half2(dFdy(vQuadEdge_Stage0.xy));
90 if (vQuadEdge_Stage0.z > 0.0 && vQuadEdge_Stage0.w > 0.0) {
91 edgeAlpha = min(min(vQuadEdge_Stage0.z, vQuadEdge_Stage0.w) + 0.5, 1.0);
92 } else {
93 half2 gF = half2(2.0 * vQuadEdge_Stage0.x * duvdx.x - duvdx.y,
94 2.0 * vQuadEdge_Stage0.x * duvdy.x - duvdy.y);
95 edgeAlpha = (vQuadEdge_Stage0.x*vQuadEdge_Stage0.x - vQuadEdge_Stage0.y);
96 edgeAlpha = saturate(0.5 - edgeAlpha / length(gF));
97 }
98 outputCoverage_Stage0 = half4(edgeAlpha);
99 }
100 { // Xfer Processor: Custom Xfermode
101 if (all(lessThanEqual(outputCoverage_Stage0.rgb, half3(0)))) {
102 discard;
103 }
104 // Read color from copy of the destination.
105 half2 _dstTexCoord = (half2(sk_FragCoord.xy) - uDstTextureUpperLeft_Stage1) *
106 uDstTextureCoordScale_Stage1;
107 _dstTexCoord.y = 1.0 - _dstTexCoord.y;
Ethan Nicholas13863662019-07-29 13:05:15 -0400108 half4 _dstColor = sample(uDstTextureSampler_Stage1, _dstTexCoord);
Ethan Nicholas40679c32019-05-31 17:06:53 -0400109 sk_FragColor.a = outputColor_Stage0.a + (1.0 - outputColor_Stage0.a) * _dstColor.a;
110 half4 srcDstAlpha = outputColor_Stage0 * _dstColor.a;
111 sk_FragColor.rgb = set_luminance_Stage1(_dstColor.rgb * outputColor_Stage0.a,
112 srcDstAlpha.a, srcDstAlpha.rgb);
113 sk_FragColor.rgb += (1.0 - outputColor_Stage0.a) * _dstColor.rgb + (1.0 - _dstColor.a) *
114 outputColor_Stage0.rgb;
115 sk_FragColor = outputCoverage_Stage0 * sk_FragColor +
116 (half4(1.0) - outputCoverage_Stage0) * _dstColor;
117 }
118 }
119)"); )
Brian Osman68870aa2020-07-08 14:12:43 -0400120
Brian Osman24b8a8c2020-07-09 10:04:33 -0400121#if defined(SK_BUILD_FOR_UNIX)
122
123#include <malloc.h>
124
Brian Osman68870aa2020-07-08 14:12:43 -0400125// These benchmarks aren't timed, they produce memory usage statistics. They run standalone, and
126// directly add their results to the nanobench log.
127void RunSkSLMemoryBenchmarks(NanoJSONResultsWriter* log) {
Brian Osman24b8a8c2020-07-09 10:04:33 -0400128 auto heap_bytes_used = []() { return mallinfo().uordblks; };
129 auto bench = [log](const char* name, int bytes) {
Brian Osman68870aa2020-07-08 14:12:43 -0400130 log->beginObject(name); // test
131 log->beginObject("meta"); // config
Brian Osman24b8a8c2020-07-09 10:04:33 -0400132 log->appendS32("bytes", bytes); // sub_result
Brian Osman68870aa2020-07-08 14:12:43 -0400133 log->endObject(); // config
134 log->endObject(); // test
135 };
136
137 {
Brian Osman24b8a8c2020-07-09 10:04:33 -0400138 int before = heap_bytes_used();
Brian Osman68870aa2020-07-08 14:12:43 -0400139 SkSL::Compiler compiler;
Brian Osman24b8a8c2020-07-09 10:04:33 -0400140 int after = heap_bytes_used();
141 bench("sksl_compiler_baseline", after - before);
Brian Osman68870aa2020-07-08 14:12:43 -0400142 }
143}
Brian Osman24b8a8c2020-07-09 10:04:33 -0400144
145#else
146
147void RunSkSLMemoryBenchmarks(NanoJSONResultsWriter*) {}
148
149#endif