Ethan Nicholas | 40679c3 | 2019-05-31 17:06:53 -0400 | [diff] [blame] | 1 | /* |
Ethan Nicholas | fc99416 | 2019-06-06 10:04:27 -0400 | [diff] [blame] | 2 | * Copyright 2019 Google LLC |
Ethan Nicholas | 40679c3 | 2019-05-31 17:06:53 -0400 | [diff] [blame] | 3 | * |
| 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" |
| 8 | #include "src/sksl/SkSLCompiler.h" |
| 9 | |
| 10 | class SkSLBench : public Benchmark { |
| 11 | public: |
| 12 | SkSLBench(SkSL::String name, const char* src) |
| 13 | : fName("sksl_" + name) |
| 14 | , fSrc(src) {} |
| 15 | |
| 16 | protected: |
| 17 | const char* onGetName() override { |
| 18 | return fName.c_str(); |
| 19 | } |
| 20 | |
| 21 | bool isSuitableFor(Backend backend) override { |
| 22 | return backend == kNonRendering_Backend; |
| 23 | } |
| 24 | |
| 25 | void onDraw(int loops, SkCanvas*) override { |
| 26 | for (int i = 0; i < loops; i++) { |
| 27 | std::unique_ptr<SkSL::Program> program = fCompiler.convertProgram( |
| 28 | SkSL::Program::kFragment_Kind, |
| 29 | fSrc, |
| 30 | fSettings); |
| 31 | if (!fCompiler.errorCount()) { |
| 32 | fCompiler.optimize(*program); |
| 33 | } else { |
| 34 | printf("%s\n", fCompiler.errorText().c_str()); |
| 35 | SK_ABORT("shader compilation failed"); |
| 36 | } |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | private: |
| 41 | SkSL::String fName; |
| 42 | SkSL::String fSrc; |
| 43 | SkSL::Compiler fCompiler; |
| 44 | SkSL::Program::Settings fSettings; |
| 45 | |
| 46 | typedef Benchmark INHERITED; |
| 47 | }; |
| 48 | |
| 49 | /////////////////////////////////////////////////////////////////////////////// |
| 50 | |
| 51 | DEF_BENCH(return new SkSLBench("tiny", "void main() { sk_FragColor = half4(1); }"); ) |
| 52 | DEF_BENCH(return new SkSLBench("huge", R"( |
| 53 | uniform half2 uDstTextureUpperLeft_Stage1; |
| 54 | uniform half2 uDstTextureCoordScale_Stage1; |
| 55 | uniform sampler2D uDstTextureSampler_Stage1; |
| 56 | noperspective in half4 vQuadEdge_Stage0; |
| 57 | noperspective in half4 vinColor_Stage0; |
| 58 | out half4 sk_FragColor; |
| 59 | half luminance_Stage1(half3 color) { |
| 60 | return dot(half3(0.3, 0.59, 0.11), color); |
| 61 | } |
| 62 | |
| 63 | half3 set_luminance_Stage1(half3 hueSat, half alpha, half3 lumColor) { |
| 64 | half diff = luminance_Stage1(lumColor - hueSat); |
| 65 | half3 outColor = hueSat + diff; |
| 66 | half outLum = luminance_Stage1(outColor); |
| 67 | half minComp = min(min(outColor.r, outColor.g), outColor.b); |
| 68 | half maxComp = max(max(outColor.r, outColor.g), outColor.b); |
| 69 | if (minComp < 0.0 && outLum != minComp) { |
| 70 | outColor = outLum + ((outColor - half3(outLum, outLum, outLum)) * outLum) / |
| 71 | (outLum - minComp); |
| 72 | } |
| 73 | if (maxComp > alpha && maxComp != outLum) { |
| 74 | outColor = outLum +((outColor - half3(outLum, outLum, outLum)) * (alpha - outLum)) / |
| 75 | (maxComp - outLum); |
| 76 | } |
| 77 | return outColor; |
| 78 | } |
| 79 | |
| 80 | void main() { |
| 81 | half4 outputColor_Stage0; |
| 82 | half4 outputCoverage_Stage0; |
| 83 | { // Stage 0, QuadEdge |
| 84 | outputColor_Stage0 = vinColor_Stage0; |
| 85 | half edgeAlpha; |
| 86 | half2 duvdx = half2(dFdx(vQuadEdge_Stage0.xy)); |
| 87 | half2 duvdy = half2(dFdy(vQuadEdge_Stage0.xy)); |
| 88 | if (vQuadEdge_Stage0.z > 0.0 && vQuadEdge_Stage0.w > 0.0) { |
| 89 | edgeAlpha = min(min(vQuadEdge_Stage0.z, vQuadEdge_Stage0.w) + 0.5, 1.0); |
| 90 | } else { |
| 91 | half2 gF = half2(2.0 * vQuadEdge_Stage0.x * duvdx.x - duvdx.y, |
| 92 | 2.0 * vQuadEdge_Stage0.x * duvdy.x - duvdy.y); |
| 93 | edgeAlpha = (vQuadEdge_Stage0.x*vQuadEdge_Stage0.x - vQuadEdge_Stage0.y); |
| 94 | edgeAlpha = saturate(0.5 - edgeAlpha / length(gF)); |
| 95 | } |
| 96 | outputCoverage_Stage0 = half4(edgeAlpha); |
| 97 | } |
| 98 | { // Xfer Processor: Custom Xfermode |
| 99 | if (all(lessThanEqual(outputCoverage_Stage0.rgb, half3(0)))) { |
| 100 | discard; |
| 101 | } |
| 102 | // Read color from copy of the destination. |
| 103 | half2 _dstTexCoord = (half2(sk_FragCoord.xy) - uDstTextureUpperLeft_Stage1) * |
| 104 | uDstTextureCoordScale_Stage1; |
| 105 | _dstTexCoord.y = 1.0 - _dstTexCoord.y; |
Ethan Nicholas | 1386366 | 2019-07-29 13:05:15 -0400 | [diff] [blame] | 106 | half4 _dstColor = sample(uDstTextureSampler_Stage1, _dstTexCoord); |
Ethan Nicholas | 40679c3 | 2019-05-31 17:06:53 -0400 | [diff] [blame] | 107 | sk_FragColor.a = outputColor_Stage0.a + (1.0 - outputColor_Stage0.a) * _dstColor.a; |
| 108 | half4 srcDstAlpha = outputColor_Stage0 * _dstColor.a; |
| 109 | sk_FragColor.rgb = set_luminance_Stage1(_dstColor.rgb * outputColor_Stage0.a, |
| 110 | srcDstAlpha.a, srcDstAlpha.rgb); |
| 111 | sk_FragColor.rgb += (1.0 - outputColor_Stage0.a) * _dstColor.rgb + (1.0 - _dstColor.a) * |
| 112 | outputColor_Stage0.rgb; |
| 113 | sk_FragColor = outputCoverage_Stage0 * sk_FragColor + |
| 114 | (half4(1.0) - outputCoverage_Stage0) * _dstColor; |
| 115 | } |
| 116 | } |
| 117 | )"); ) |