1 /* 2 * Copyright 2016 Google Inc. 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 8 #include "Benchmark.h" 9 #include "SkOpts.h" 10 #include "SkRasterPipeline.h" 11 #include "../src/jumper/SkJumper.h" 12 13 static const int N = 15; 14 15 static uint64_t dst[N]; // sRGB or F16 16 static uint32_t src[N]; // sRGB 17 static uint8_t mask[N]; // 8-bit linear 18 19 // We'll build up a somewhat realistic useful pipeline: 20 // - load srgb src 21 // - scale src by 8-bit mask 22 // - load srgb/f16 dst 23 // - src = srcover(dst, src) 24 // - store src back as srgb/f16 25 26 template <bool kF16> 27 class SkRasterPipelineBench : public Benchmark { 28 public: 29 bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; } 30 const char* onGetName() override { 31 switch ((int)kF16) { 32 case 0: return "SkRasterPipeline_srgb"; 33 case 1: return "SkRasterPipeline_f16"; 34 } 35 return "whoops"; 36 } 37 38 void onDraw(int loops, SkCanvas*) override { 39 SkJumper_MemoryCtx mask_ctx = {mask, 0}, 40 src_ctx = {src, 0}, 41 dst_ctx = {dst, 0}; 42 43 SkRasterPipeline_<256> p; 44 p.append(SkRasterPipeline::load_8888, &src_ctx); 45 p.append(SkRasterPipeline::from_srgb); 46 p.append(SkRasterPipeline::scale_u8, &mask_ctx); 47 p.append(SkRasterPipeline::move_src_dst); 48 if (kF16) { 49 p.append(SkRasterPipeline::load_f16, &dst_ctx); 50 } else { 51 p.append(SkRasterPipeline::load_8888, &dst_ctx); 52 p.append(SkRasterPipeline::from_srgb); 53 } 54 p.append(SkRasterPipeline::dstover); 55 if (kF16) { 56 p.append(SkRasterPipeline::store_f16, &dst_ctx); 57 } else { 58 p.append(SkRasterPipeline::to_srgb); 59 p.append(SkRasterPipeline::store_8888, &dst_ctx); 60 } 61 62 while (loops --> 0) { 63 p.run(0,0,N,1); 64 } 65 } 66 }; 67 DEF_BENCH( return (new SkRasterPipelineBench< true>); ) 68 DEF_BENCH( return (new SkRasterPipelineBench<false>); ) 69 70 class SkRasterPipelineCompileVsRunBench : public Benchmark { 71 public: 72 explicit SkRasterPipelineCompileVsRunBench(bool compile) : fCompile(compile) {} 73 bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; } 74 const char* onGetName() override { 75 return fCompile ? "SkRasterPipeline_compile" 76 : "SkRasterPipeline_run"; 77 } 78 79 void onDraw(int loops, SkCanvas*) override { 80 SkJumper_MemoryCtx src_ctx = {src, 0}, 81 dst_ctx = {dst, 0}; 82 83 SkRasterPipeline_<256> p; 84 p.append(SkRasterPipeline::load_8888, &dst_ctx); 85 p.append(SkRasterPipeline::move_src_dst); 86 p.append(SkRasterPipeline::load_8888, &src_ctx); 87 p.append(SkRasterPipeline::srcover); 88 p.append(SkRasterPipeline::store_8888, &dst_ctx); 89 90 if (fCompile) { 91 auto fn = p.compile(); 92 while (loops --> 0) { 93 fn(0,0,N,1); 94 } 95 } else { 96 while (loops --> 0) { 97 p.run(0,0,N,1); 98 } 99 } 100 } 101 private: 102 bool fCompile; 103 }; 104 DEF_BENCH( return (new SkRasterPipelineCompileVsRunBench(true )); ) 105 DEF_BENCH( return (new SkRasterPipelineCompileVsRunBench(false)); ) 106 107 static SkColorSpaceTransferFn gamma(float g) { 108 SkColorSpaceTransferFn fn = {0,0,0,0,0,0,0}; 109 fn.fG = g; 110 fn.fA = 1; 111 return fn; 112 } 113 114 class SkRasterPipeline_2dot2 : public Benchmark { 115 public: 116 SkRasterPipeline_2dot2(bool parametric) : fParametric(parametric) {} 117 118 bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; } 119 const char* onGetName() override { 120 return fParametric ? "SkRasterPipeline_2dot2_parametric" 121 : "SkRasterPipeline_2dot2_gamma"; 122 } 123 124 void onDraw(int loops, SkCanvas*) override { 125 SkColor4f c = { 1.0f, 1.0f, 1.0f, 1.0f }; 126 127 SkColorSpaceTransferFn from_2dot2 = gamma( 2.2f), 128 to_2dot2 = gamma(1/2.2f); 129 SkSTArenaAlloc<256> alloc; 130 SkRasterPipeline p(&alloc); 131 p.append_constant_color(&alloc, c); 132 if (fParametric) { 133 p.append(SkRasterPipeline::parametric_r, &from_2dot2); 134 p.append(SkRasterPipeline::parametric_g, &from_2dot2); 135 p.append(SkRasterPipeline::parametric_b, &from_2dot2); 136 p.append(SkRasterPipeline::parametric_r, & to_2dot2); 137 p.append(SkRasterPipeline::parametric_g, & to_2dot2); 138 p.append(SkRasterPipeline::parametric_b, & to_2dot2); 139 } else { 140 p.append(SkRasterPipeline::gamma, &from_2dot2.fG); 141 p.append(SkRasterPipeline::gamma, & to_2dot2.fG); 142 } 143 144 while (loops --> 0) { 145 p.run(0,0,N,1); 146 } 147 } 148 private: 149 bool fParametric; 150 }; 151 DEF_BENCH( return (new SkRasterPipeline_2dot2( true)); ) 152 DEF_BENCH( return (new SkRasterPipeline_2dot2(false)); ) 153 154 class SkRasterPipelineToSRGB : public Benchmark { 155 public: 156 bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; } 157 const char* onGetName() override { 158 return "SkRasterPipeline_to_srgb"; 159 } 160 161 void onDraw(int loops, SkCanvas*) override { 162 SkRasterPipeline_<256> p; 163 p.append(SkRasterPipeline::to_srgb); 164 165 while (loops --> 0) { 166 p.run(0,0,N,1); 167 } 168 } 169 }; 170 DEF_BENCH( return (new SkRasterPipelineToSRGB); ) 171