blob: c6fb6f0a781223e43b709e369243ac6922f1d7df [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 Nicholasba9a04f2020-11-06 09:28:04 -050010#include "include/core/SkCanvas.h"
11#include "src/gpu/GrCaps.h"
12#include "src/gpu/GrRecordingContextPriv.h"
13#include "src/gpu/mock/GrMockCaps.h"
Ethan Nicholas40679c32019-05-31 17:06:53 -040014#include "src/sksl/SkSLCompiler.h"
Ethan Nicholasba9a04f2020-11-06 09:28:04 -050015#include "src/sksl/SkSLIRGenerator.h"
16#include "src/sksl/SkSLParser.h"
Ethan Nicholas40679c32019-05-31 17:06:53 -040017
Brian Osman24c5d242020-09-29 15:08:55 -040018class SkSLCompilerStartupBench : public Benchmark {
19protected:
20 const char* onGetName() override {
21 return "sksl_compiler_startup";
22 }
23
24 bool isSuitableFor(Backend backend) override {
25 return backend == kNonRendering_Backend;
26 }
27
28 void onDraw(int loops, SkCanvas*) override {
Brian Osman0006ad02020-11-18 15:38:39 -050029 GrShaderCaps caps(GrContextOptions{});
Brian Osman24c5d242020-09-29 15:08:55 -040030 for (int i = 0; i < loops; i++) {
Brian Osman0006ad02020-11-18 15:38:39 -050031 SkSL::Compiler compiler(&caps);
Brian Osman24c5d242020-09-29 15:08:55 -040032 }
33 }
34};
35
36DEF_BENCH(return new SkSLCompilerStartupBench();)
37
Ethan Nicholasba9a04f2020-11-06 09:28:04 -050038enum class Output {
39 kNone,
40 kGLSL,
41 kMetal,
42 kSPIRV
43};
44
45class SkSLCompileBench : public Benchmark {
Ethan Nicholas40679c32019-05-31 17:06:53 -040046public:
Ethan Nicholasba9a04f2020-11-06 09:28:04 -050047 static const char* output_string(Output output) {
48 switch (output) {
49 case Output::kNone: return "";
50 case Output::kGLSL: return "glsl_";
51 case Output::kMetal: return "metal_";
52 case Output::kSPIRV: return "spirv_";
53 }
54 SkUNREACHABLE;
55 }
56
57 SkSLCompileBench(SkSL::String name, const char* src, bool optimize, Output output)
58 : fName(SkSL::String("sksl_") + (optimize ? "" : "unoptimized_") + output_string(output) +
59 name)
60 , fSrc(src)
61 , fCaps(GrContextOptions(), GrMockOptions())
62 , fCompiler(fCaps.shaderCaps())
63 , fOutput(output) {
64 fSettings.fOptimize = optimize;
65 // The test programs we compile don't follow Vulkan rules and thus produce invalid
66 // SPIR-V. This is harmless, so long as we don't try to validate them.
67 fSettings.fValidateSPIRV = false;
68 }
69
70protected:
71 const char* onGetName() override {
72 return fName.c_str();
73 }
74
75 bool isSuitableFor(Backend backend) override {
76 return backend == kNonRendering_Backend;
77 }
78
79 void onDraw(int loops, SkCanvas* canvas) override {
80 for (int i = 0; i < loops; i++) {
81 std::unique_ptr<SkSL::Program> program = fCompiler.convertProgram(
82 SkSL::Program::kFragment_Kind,
83 fSrc,
84 fSettings);
85 if (fCompiler.errorCount()) {
86 SK_ABORT("shader compilation failed: %s\n", fCompiler.errorText().c_str());
87 }
88 SkSL::String result;
89 switch (fOutput) {
90 case Output::kNone: break;
91 case Output::kGLSL: SkAssertResult(fCompiler.toGLSL(*program, &result)); break;
92 case Output::kMetal: SkAssertResult(fCompiler.toMetal(*program, &result)); break;
93 case Output::kSPIRV: SkAssertResult(fCompiler.toSPIRV(*program, &result)); break;
94 }
95 }
96 }
97
98private:
99 SkSL::String fName;
100 SkSL::String fSrc;
101 GrMockCaps fCaps;
102 SkSL::Compiler fCompiler;
103 SkSL::Program::Settings fSettings;
104 Output fOutput;
105
106 using INHERITED = Benchmark;
107};
108
109class SkSLParseBench : public Benchmark {
110public:
111 SkSLParseBench(SkSL::String name, const char* src)
112 : fName("sksl_parse_" + name)
Brian Osmand7e76592020-11-02 12:26:22 -0500113 , fSrc(src)
Brian Osman0006ad02020-11-18 15:38:39 -0500114 , fCaps(GrContextOptions())
115 , fCompiler(&fCaps) {}
Ethan Nicholas40679c32019-05-31 17:06:53 -0400116
117protected:
118 const char* onGetName() override {
119 return fName.c_str();
120 }
121
122 bool isSuitableFor(Backend backend) override {
123 return backend == kNonRendering_Backend;
124 }
125
Ethan Nicholasba9a04f2020-11-06 09:28:04 -0500126 void onDelayedSetup() override {
127 SkSL::ParsedModule module = fCompiler.moduleForProgramKind(
128 SkSL::Program::Kind::kFragment_Kind);
129 fCompiler.irGenerator().setSymbolTable(module.fSymbols);
130 }
131
Ethan Nicholas40679c32019-05-31 17:06:53 -0400132 void onDraw(int loops, SkCanvas*) override {
133 for (int i = 0; i < loops; i++) {
Ethan Nicholasba9a04f2020-11-06 09:28:04 -0500134 fCompiler.irGenerator().pushSymbolTable();
135 SkSL::Parser parser(fSrc.c_str(), fSrc.length(), *fCompiler.irGenerator().symbolTable(),
136 fCompiler);
137 parser.compilationUnit();
138 fCompiler.irGenerator().popSymbolTable();
Ethan Nicholas34b19c52020-09-14 11:33:47 -0400139 if (fCompiler.errorCount()) {
Ethan Nicholasba9a04f2020-11-06 09:28:04 -0500140 SK_ABORT("shader compilation failed: %s\n", fCompiler.errorText().c_str());
Ethan Nicholas40679c32019-05-31 17:06:53 -0400141 }
142 }
143 }
144
145private:
146 SkSL::String fName;
147 SkSL::String fSrc;
Brian Osman0006ad02020-11-18 15:38:39 -0500148 GrShaderCaps fCaps;
Ethan Nicholas40679c32019-05-31 17:06:53 -0400149 SkSL::Compiler fCompiler;
150 SkSL::Program::Settings fSettings;
151
John Stiles7571f9e2020-09-02 22:42:33 -0400152 using INHERITED = Benchmark;
Ethan Nicholas40679c32019-05-31 17:06:53 -0400153};
154
155///////////////////////////////////////////////////////////////////////////////
156
Ethan Nicholasba9a04f2020-11-06 09:28:04 -0500157#define COMPILER_BENCH(name, text) \
158static constexpr char name ## _SRC[] = text; \
159DEF_BENCH(return new SkSLParseBench(#name, name ## _SRC);) \
160DEF_BENCH(return new SkSLCompileBench(#name, name ## _SRC, /*optimize=*/false, Output::kNone);) \
161DEF_BENCH(return new SkSLCompileBench(#name, name ## _SRC, /*optimize=*/true, Output::kNone);) \
162DEF_BENCH(return new SkSLCompileBench(#name, name ## _SRC, /*optimize=*/true, Output::kGLSL);) \
163DEF_BENCH(return new SkSLCompileBench(#name, name ## _SRC, /*optimize=*/true, Output::kMetal);) \
164DEF_BENCH(return new SkSLCompileBench(#name, name ## _SRC, /*optimize=*/true, Output::kSPIRV);)
165
166// Metal requires a layout set and binding for all of its uniforms. We just care that these shaders
167// compile, not that they actually work, so we just fill them with zeroes.
168COMPILER_BENCH(large, R"(
169layout(set=0, binding=0) uniform half urange_Stage1;
170layout(set=0, binding=0) uniform half4 uleftBorderColor_Stage1_c0_c0;
171layout(set=0, binding=0) uniform half4 urightBorderColor_Stage1_c0_c0;
172layout(set=0, binding=0) uniform float3x3 umatrix_Stage1_c0_c0_c0;
173layout(set=0, binding=0) uniform half2 ufocalParams_Stage1_c0_c0_c0_c0;
174layout(set=0, binding=0) uniform float4 uscale0_1_Stage1_c0_c0_c1;
175layout(set=0, binding=0) uniform float4 uscale2_3_Stage1_c0_c0_c1;
176layout(set=0, binding=0) uniform float4 uscale4_5_Stage1_c0_c0_c1;
177layout(set=0, binding=0) uniform float4 uscale6_7_Stage1_c0_c0_c1;
178layout(set=0, binding=0) uniform float4 ubias0_1_Stage1_c0_c0_c1;
179layout(set=0, binding=0) uniform float4 ubias2_3_Stage1_c0_c0_c1;
180layout(set=0, binding=0) uniform float4 ubias4_5_Stage1_c0_c0_c1;
181layout(set=0, binding=0) uniform float4 ubias6_7_Stage1_c0_c0_c1;
182layout(set=0, binding=0) uniform half4 uthresholds1_7_Stage1_c0_c0_c1;
183layout(set=0, binding=0) uniform half4 uthresholds9_13_Stage1_c0_c0_c1;
John Stiles7f88b722020-09-30 09:29:13 -0400184flat in half4 vcolor_Stage0;
185in float vcoverage_Stage0;
186flat in float4 vgeomSubset_Stage0;
187in float2 vTransformedCoords_0_Stage0;
188out half4 sk_FragColor;
189half4 TwoPointConicalGradientLayout_Stage1_c0_c0_c0_c0(half4 _input)
190{
191 half4 _output;
192 float t = -1.0;
193 half v = 1.0;
194 @switch (2)
195 {
196 case 1:
197 {
198 half r0_2 = ufocalParams_Stage1_c0_c0_c0_c0.y;
199 t = float(r0_2) - vTransformedCoords_0_Stage0.y * vTransformedCoords_0_Stage0.y;
200 if (t >= 0.0)
201 {
202 t = vTransformedCoords_0_Stage0.x + sqrt(t);
203 }
204 else
205 {
206 v = -1.0;
207 }
208 }
209 break;
210 case 0:
211 {
212 half r0 = ufocalParams_Stage1_c0_c0_c0_c0.x;
213 @if (true)
214 {
215 t = length(vTransformedCoords_0_Stage0) - float(r0);
216 }
217 else
218 {
219 t = -length(vTransformedCoords_0_Stage0) - float(r0);
220 }
221 }
222 break;
223 case 2:
224 {
225 half invR1 = ufocalParams_Stage1_c0_c0_c0_c0.x;
226 half fx = ufocalParams_Stage1_c0_c0_c0_c0.y;
227 float x_t = -1.0;
228 @if (false)
229 {
230 x_t = dot(vTransformedCoords_0_Stage0, vTransformedCoords_0_Stage0) / vTransformedCoords_0_Stage0.x;
231 }
232 else if (true)
233 {
234 x_t = length(vTransformedCoords_0_Stage0) - vTransformedCoords_0_Stage0.x * float(invR1);
235 }
236 else
237 {
238 float temp = vTransformedCoords_0_Stage0.x * vTransformedCoords_0_Stage0.x - vTransformedCoords_0_Stage0.y * vTransformedCoords_0_Stage0.y;
239 if (temp >= 0.0)
240 {
241 @if (false || !true)
242 {
243 x_t = -sqrt(temp) - vTransformedCoords_0_Stage0.x * float(invR1);
244 }
245 else
246 {
247 x_t = sqrt(temp) - vTransformedCoords_0_Stage0.x * float(invR1);
248 }
249 }
250 }
251 @if (!true)
252 {
253 if (x_t <= 0.0)
254 {
255 v = -1.0;
256 }
257 }
258 @if (true)
259 {
260 @if (false)
261 {
262 t = x_t;
263 }
264 else
265 {
266 t = x_t + float(fx);
267 }
268 }
269 else
270 {
271 @if (false)
272 {
273 t = -x_t;
274 }
275 else
276 {
277 t = -x_t + float(fx);
278 }
279 }
280 @if (false)
281 {
282 t = 1.0 - t;
283 }
284 }
285 break;
286 }
287 _output = half4(half(t), v, 0.0, 0.0);
288 return _output;
289}
290half4 MatrixEffect_Stage1_c0_c0_c0(half4 _input)
291{
292 half4 _output;
293 _output = TwoPointConicalGradientLayout_Stage1_c0_c0_c0_c0(_input);
294 return _output;
295}
296half4 UnrolledBinaryGradientColorizer_Stage1_c0_c0_c1(half4 _input, float2 _coords)
297{
298 half4 _output;
299 half t = half(_coords.x);
300 float4 scale, bias;
301 if (4 <= 4 || t < uthresholds1_7_Stage1_c0_c0_c1.w)
302 {
303 if (4 <= 2 || t < uthresholds1_7_Stage1_c0_c0_c1.y)
304 {
305 if (4 <= 1 || t < uthresholds1_7_Stage1_c0_c0_c1.x)
306 {
307 scale = uscale0_1_Stage1_c0_c0_c1;
308 bias = ubias0_1_Stage1_c0_c0_c1;
309 }
310 else
311 {
312 scale = uscale2_3_Stage1_c0_c0_c1;
313 bias = ubias2_3_Stage1_c0_c0_c1;
314 }
315 }
316 else
317 {
318 if (4 <= 3 || t < uthresholds1_7_Stage1_c0_c0_c1.z)
319 {
320 scale = uscale4_5_Stage1_c0_c0_c1;
321 bias = ubias4_5_Stage1_c0_c0_c1;
322 }
323 else
324 {
325 scale = uscale6_7_Stage1_c0_c0_c1;
326 bias = ubias6_7_Stage1_c0_c0_c1;
327 }
328 }
329 }
330 else
331 {
332 if (4 <= 6 || t < uthresholds9_13_Stage1_c0_c0_c1.y)
333 {
334 if (4 <= 5 || t < uthresholds9_13_Stage1_c0_c0_c1.x)
335 {
336 scale = float4(0);
337 bias = float4(0);
338 }
339 else
340 {
341 scale = float4(0);
342 bias = float4(0);
343 }
344 }
345 else
346 {
347 if (4 <= 7 || t < uthresholds9_13_Stage1_c0_c0_c1.z)
348 {
349 scale = float4(0);
350 bias = float4(0);
351 }
352 else
353 {
354 scale = float4(0);
355 bias = float4(0);
356 }
357 }
358 }
359 _output = half4(float(t) * scale + bias);
360 return _output;
361}
362half4 ClampedGradientEffect_Stage1_c0_c0(half4 _input)
363{
364 half4 _output;
365 half4 t = MatrixEffect_Stage1_c0_c0_c0(_input);
366 if (!false && t.y < 0.0)
367 {
368 _output = half4(0.0);
369 }
370 else if (t.x < 0.0)
371 {
372 _output = uleftBorderColor_Stage1_c0_c0;
373 }
374 else if (t.x > 1.0)
375 {
376 _output = urightBorderColor_Stage1_c0_c0;
377 }
378 else
379 {
380 _output = UnrolledBinaryGradientColorizer_Stage1_c0_c0_c1(_input, float2(half2(t.x, 0.0)));
381 }
382 @if (false)
383 {
384 _output.xyz *= _output.w;
385 }
386 return _output;
387}
388half4 OverrideInputFragmentProcessor_Stage1_c0(half4 _input)
389{
390 half4 _output;
391 half4 constColor;
392 @if (false)
393 {
394 constColor = half4(0);
395 }
396 else
397 {
398 constColor = half4(1.000000, 1.000000, 1.000000, 1.000000);
399 }
400 _output = ClampedGradientEffect_Stage1_c0_c0(constColor);
401 return _output;
402}
403void main()
404{
405 half4 outputColor_Stage0;
406 half4 outputCoverage_Stage0;
407 {
408 // Stage 0, QuadPerEdgeAAGeometryProcessor
409 outputColor_Stage0 = vcolor_Stage0;
410 float coverage = vcoverage_Stage0 * sk_FragCoord.w;
411 float4 geoSubset;
412 geoSubset = vgeomSubset_Stage0;
413 if (coverage < 0.5)
414 {
415 float4 dists4 = clamp(float4(1, 1, -1, -1) * (sk_FragCoord.xyxy - geoSubset), 0, 1);
416 float2 dists2 = dists4.xy * dists4.zw;
417 coverage = min(coverage, dists2.x * dists2.y);
418 }
419 outputCoverage_Stage0 = half4(half(coverage));
420 }
421 half4 output_Stage1;
422 {
423 // Stage 1, DitherEffect
424 half4 color = OverrideInputFragmentProcessor_Stage1_c0(outputColor_Stage0);
425 half value;
426 @if (sk_Caps.integerSupport)
427 {
428 uint x = uint(sk_FragCoord.x);
429 uint y = uint(sk_FragCoord.y) ^ x;
430 uint m = (((((y & 1) << 5 | (x & 1) << 4) | (y & 2) << 2) | (x & 2) << 1) | (y & 4) >> 1) | (x & 4) >> 2;
431 value = half(m) / 64.0 - 0.4921875;
432 }
433 else
434 {
435 half4 bits = mod(half4(sk_FragCoord.yxyx), half4(2.0, 2.0, 4.0, 4.0));
436 bits.zw = step(2.0, bits.zw);
437 bits.xz = abs(bits.xz - bits.yw);
438 value = dot(bits, half4(0.5, 0.25, 0.125, 0.0625)) - 0.46875;
439 }
440 output_Stage1 = half4(clamp(color.xyz + value * urange_Stage1, 0.0, color.w), color.w);
441 }
442 {
443 // Xfer Processor: Porter Duff
444 sk_FragColor = output_Stage1 * outputCoverage_Stage0;
445 }
446}
Ethan Nicholasba9a04f2020-11-06 09:28:04 -0500447)");
John Stiles7f88b722020-09-30 09:29:13 -0400448
Ethan Nicholasba9a04f2020-11-06 09:28:04 -0500449COMPILER_BENCH(medium, R"(
450 layout(set=0, binding=0) uniform half2 uDstTextureUpperLeft_Stage1;
451 layout(set=0, binding=0) uniform half2 uDstTextureCoordScale_Stage1;
452 layout(set=0, binding=0) uniform sampler2D uDstTextureSampler_Stage1;
Ethan Nicholas40679c32019-05-31 17:06:53 -0400453 noperspective in half4 vQuadEdge_Stage0;
454 noperspective in half4 vinColor_Stage0;
455 out half4 sk_FragColor;
456 half luminance_Stage1(half3 color) {
457 return dot(half3(0.3, 0.59, 0.11), color);
458 }
459
460 half3 set_luminance_Stage1(half3 hueSat, half alpha, half3 lumColor) {
461 half diff = luminance_Stage1(lumColor - hueSat);
462 half3 outColor = hueSat + diff;
463 half outLum = luminance_Stage1(outColor);
464 half minComp = min(min(outColor.r, outColor.g), outColor.b);
465 half maxComp = max(max(outColor.r, outColor.g), outColor.b);
466 if (minComp < 0.0 && outLum != minComp) {
467 outColor = outLum + ((outColor - half3(outLum, outLum, outLum)) * outLum) /
468 (outLum - minComp);
469 }
470 if (maxComp > alpha && maxComp != outLum) {
471 outColor = outLum +((outColor - half3(outLum, outLum, outLum)) * (alpha - outLum)) /
472 (maxComp - outLum);
473 }
474 return outColor;
475 }
476
477 void main() {
478 half4 outputColor_Stage0;
479 half4 outputCoverage_Stage0;
480 { // Stage 0, QuadEdge
481 outputColor_Stage0 = vinColor_Stage0;
482 half edgeAlpha;
483 half2 duvdx = half2(dFdx(vQuadEdge_Stage0.xy));
484 half2 duvdy = half2(dFdy(vQuadEdge_Stage0.xy));
485 if (vQuadEdge_Stage0.z > 0.0 && vQuadEdge_Stage0.w > 0.0) {
486 edgeAlpha = min(min(vQuadEdge_Stage0.z, vQuadEdge_Stage0.w) + 0.5, 1.0);
487 } else {
488 half2 gF = half2(2.0 * vQuadEdge_Stage0.x * duvdx.x - duvdx.y,
489 2.0 * vQuadEdge_Stage0.x * duvdy.x - duvdy.y);
490 edgeAlpha = (vQuadEdge_Stage0.x*vQuadEdge_Stage0.x - vQuadEdge_Stage0.y);
491 edgeAlpha = saturate(0.5 - edgeAlpha / length(gF));
492 }
493 outputCoverage_Stage0 = half4(edgeAlpha);
494 }
495 { // Xfer Processor: Custom Xfermode
496 if (all(lessThanEqual(outputCoverage_Stage0.rgb, half3(0)))) {
497 discard;
498 }
499 // Read color from copy of the destination.
500 half2 _dstTexCoord = (half2(sk_FragCoord.xy) - uDstTextureUpperLeft_Stage1) *
501 uDstTextureCoordScale_Stage1;
502 _dstTexCoord.y = 1.0 - _dstTexCoord.y;
Ethan Nicholas13863662019-07-29 13:05:15 -0400503 half4 _dstColor = sample(uDstTextureSampler_Stage1, _dstTexCoord);
Ethan Nicholas40679c32019-05-31 17:06:53 -0400504 sk_FragColor.a = outputColor_Stage0.a + (1.0 - outputColor_Stage0.a) * _dstColor.a;
505 half4 srcDstAlpha = outputColor_Stage0 * _dstColor.a;
506 sk_FragColor.rgb = set_luminance_Stage1(_dstColor.rgb * outputColor_Stage0.a,
507 srcDstAlpha.a, srcDstAlpha.rgb);
508 sk_FragColor.rgb += (1.0 - outputColor_Stage0.a) * _dstColor.rgb + (1.0 - _dstColor.a) *
509 outputColor_Stage0.rgb;
510 sk_FragColor = outputCoverage_Stage0 * sk_FragColor +
511 (half4(1.0) - outputCoverage_Stage0) * _dstColor;
512 }
513 }
Ethan Nicholasba9a04f2020-11-06 09:28:04 -0500514)");
Brian Osman68870aa2020-07-08 14:12:43 -0400515
Ethan Nicholasba9a04f2020-11-06 09:28:04 -0500516COMPILER_BENCH(small, R"(
517 layout(set=0, binding=0) uniform float3x3 umatrix_Stage1_c0_c0;
518 layout(set=0, binding=0) uniform sampler2D uTextureSampler_0_Stage1;
John Stiles312535b2020-10-23 18:37:29 -0400519 noperspective in float2 vTransformedCoords_0_Stage0;
520 out half4 sk_FragColor;
521 half4 TextureEffect_Stage1_c0_c0_c0(half4 _input)
522 {
523 half4 _output;
524 return sample(uTextureSampler_0_Stage1, vTransformedCoords_0_Stage0);
525 }
526 half4 MatrixEffect_Stage1_c0_c0(half4 _input)
527 {
528 half4 _output;
529 return TextureEffect_Stage1_c0_c0_c0(_input);
530 }
531 inline half4 Blend_Stage1_c0(half4 _input)
532 {
533 half4 _output;
534 // Blend mode: Modulate (Compose-One behavior)
535 return blend_modulate(MatrixEffect_Stage1_c0_c0(half4(1)), _input);
536 }
537 void main()
538 {
539 half4 outputColor_Stage0;
540 half4 outputCoverage_Stage0;
541 {
542 // Stage 0, QuadPerEdgeAAGeometryProcessor
543 outputColor_Stage0 = half4(1);
544 outputCoverage_Stage0 = half4(1);
545 }
546 half4 output_Stage1;
547 output_Stage1 = Blend_Stage1_c0(outputColor_Stage0);
548 {
549 // Xfer Processor: Porter Duff
550 sk_FragColor = output_Stage1 * outputCoverage_Stage0;
551 }
552 }
Ethan Nicholasba9a04f2020-11-06 09:28:04 -0500553)");
John Stiles312535b2020-10-23 18:37:29 -0400554
Ethan Nicholasba9a04f2020-11-06 09:28:04 -0500555COMPILER_BENCH(tiny, "void main() { sk_FragColor = half4(1); }");
John Stiles312535b2020-10-23 18:37:29 -0400556
Brian Osman24b8a8c2020-07-09 10:04:33 -0400557#if defined(SK_BUILD_FOR_UNIX)
558
559#include <malloc.h>
560
Brian Osman68870aa2020-07-08 14:12:43 -0400561// These benchmarks aren't timed, they produce memory usage statistics. They run standalone, and
562// directly add their results to the nanobench log.
563void RunSkSLMemoryBenchmarks(NanoJSONResultsWriter* log) {
Brian Osman24b8a8c2020-07-09 10:04:33 -0400564 auto heap_bytes_used = []() { return mallinfo().uordblks; };
565 auto bench = [log](const char* name, int bytes) {
Brian Osman68870aa2020-07-08 14:12:43 -0400566 log->beginObject(name); // test
567 log->beginObject("meta"); // config
Brian Osman24b8a8c2020-07-09 10:04:33 -0400568 log->appendS32("bytes", bytes); // sub_result
Brian Osman68870aa2020-07-08 14:12:43 -0400569 log->endObject(); // config
570 log->endObject(); // test
571 };
572
573 {
Brian Osman24b8a8c2020-07-09 10:04:33 -0400574 int before = heap_bytes_used();
Brian Osman0006ad02020-11-18 15:38:39 -0500575 GrShaderCaps caps(GrContextOptions{});
576 SkSL::Compiler compiler(&caps);
Brian Osman24b8a8c2020-07-09 10:04:33 -0400577 int after = heap_bytes_used();
578 bench("sksl_compiler_baseline", after - before);
Brian Osman68870aa2020-07-08 14:12:43 -0400579 }
580}
Brian Osman24b8a8c2020-07-09 10:04:33 -0400581
582#else
583
584void RunSkSLMemoryBenchmarks(NanoJSONResultsWriter*) {}
585
586#endif