1 /* 2 * Copyright 2019 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 "bench/Benchmark.h" 9 #include "src/core/SkOpts.h" 10 #include "src/core/SkVM.h" 11 #include "tools/SkVMBuilders.h" 12 13 namespace { 14 15 enum Mode {Opts, RP, F32, I32_Naive, I32, I32_SWAR}; 16 static const char* kMode_name[] = { "Opts", "RP","F32", "I32_Naive", "I32", "I32_SWAR" }; 17 18 } 19 20 class SkVMBench : public Benchmark { 21 public: SkVMBench(int pixels,Mode mode)22 SkVMBench(int pixels, Mode mode) 23 : fPixels(pixels) 24 , fMode(mode) 25 , fName(SkStringPrintf("SkVM_%d_%s", pixels, kMode_name[mode])) 26 {} 27 28 private: onGetName()29 const char* onGetName() override { return fName.c_str(); } isSuitableFor(Backend backend)30 bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; } 31 onDelayedSetup()32 void onDelayedSetup() override { 33 this->setUnits(fPixels); 34 fSrc.resize(fPixels, 0x7f123456); // Arbitrary non-opaque non-transparent value. 35 fDst.resize(fPixels, 0xff987654); // Arbitrary value. 36 37 if (fMode == F32 ) { fProgram = SrcoverBuilder_F32 {}.done(); } 38 if (fMode == I32_Naive) { fProgram = SrcoverBuilder_I32_Naive{}.done(); } 39 if (fMode == I32 ) { fProgram = SrcoverBuilder_I32 {}.done(); } 40 if (fMode == I32_SWAR ) { fProgram = SrcoverBuilder_I32_SWAR {}.done(); } 41 42 if (fMode == RP) { 43 fSrcCtx = { fSrc.data(), 0 }; 44 fDstCtx = { fDst.data(), 0 }; 45 fPipeline.append(SkRasterPipeline::load_8888 , &fSrcCtx); 46 fPipeline.append(SkRasterPipeline::load_8888_dst, &fDstCtx); 47 fPipeline.append(SkRasterPipeline::srcover); 48 fPipeline.append(SkRasterPipeline::store_8888, &fDstCtx); 49 } 50 51 // Trigger one run now so we can do a quick correctness check. 52 this->draw(1,nullptr); 53 for (int i = 0; i < fPixels; i++) { 54 SkASSERTF(fDst[i] == 0xff5e6f80, "Want 0xff5e6f80, got %08x", fDst[i]); 55 } 56 } 57 onDraw(int loops,SkCanvas *)58 void onDraw(int loops, SkCanvas*) override { 59 while (loops --> 0) { 60 if (fMode == Opts) { 61 SkOpts::blit_row_s32a_opaque(fDst.data(), fSrc.data(), fPixels, 0xff); 62 } else if (fMode == RP) { 63 fPipeline.run(0,0,fPixels,1); 64 } else { 65 fProgram.eval(fPixels, fSrc.data(), fDst.data()); 66 } 67 } 68 } 69 70 int fPixels; 71 Mode fMode; 72 SkString fName; 73 std::vector<uint32_t> fSrc, 74 fDst; 75 skvm::Program fProgram; 76 77 SkRasterPipeline_MemoryCtx fSrcCtx, 78 fDstCtx; 79 SkRasterPipeline_<256> fPipeline; 80 }; 81 82 DEF_BENCH(return (new SkVMBench{ 1, Opts});) 83 DEF_BENCH(return (new SkVMBench{ 4, Opts});) 84 DEF_BENCH(return (new SkVMBench{ 15, Opts});) 85 DEF_BENCH(return (new SkVMBench{ 63, Opts});) 86 DEF_BENCH(return (new SkVMBench{ 256, Opts});) 87 DEF_BENCH(return (new SkVMBench{1024, Opts});) 88 DEF_BENCH(return (new SkVMBench{4096, Opts});) 89 90 DEF_BENCH(return (new SkVMBench{ 1, RP});) 91 DEF_BENCH(return (new SkVMBench{ 4, RP});) 92 DEF_BENCH(return (new SkVMBench{ 15, RP});) 93 DEF_BENCH(return (new SkVMBench{ 63, RP});) 94 DEF_BENCH(return (new SkVMBench{ 256, RP});) 95 DEF_BENCH(return (new SkVMBench{1024, RP});) 96 DEF_BENCH(return (new SkVMBench{4096, RP});) 97 98 DEF_BENCH(return (new SkVMBench{ 1, F32});) 99 DEF_BENCH(return (new SkVMBench{ 4, F32});) 100 DEF_BENCH(return (new SkVMBench{ 15, F32});) 101 DEF_BENCH(return (new SkVMBench{ 63, F32});) 102 DEF_BENCH(return (new SkVMBench{ 256, F32});) 103 DEF_BENCH(return (new SkVMBench{1024, F32});) 104 DEF_BENCH(return (new SkVMBench{4096, F32});) 105 106 DEF_BENCH(return (new SkVMBench{ 1, I32_Naive});) 107 DEF_BENCH(return (new SkVMBench{ 4, I32_Naive});) 108 DEF_BENCH(return (new SkVMBench{ 15, I32_Naive});) 109 DEF_BENCH(return (new SkVMBench{ 63, I32_Naive});) 110 DEF_BENCH(return (new SkVMBench{ 256, I32_Naive});) 111 DEF_BENCH(return (new SkVMBench{1024, I32_Naive});) 112 DEF_BENCH(return (new SkVMBench{4096, I32_Naive});) 113 114 DEF_BENCH(return (new SkVMBench{ 1, I32});) 115 DEF_BENCH(return (new SkVMBench{ 4, I32});) 116 DEF_BENCH(return (new SkVMBench{ 15, I32});) 117 DEF_BENCH(return (new SkVMBench{ 63, I32});) 118 DEF_BENCH(return (new SkVMBench{ 256, I32});) 119 DEF_BENCH(return (new SkVMBench{1024, I32});) 120 DEF_BENCH(return (new SkVMBench{4096, I32});) 121 122 DEF_BENCH(return (new SkVMBench{ 1, I32_SWAR});) 123 DEF_BENCH(return (new SkVMBench{ 4, I32_SWAR});) 124 DEF_BENCH(return (new SkVMBench{ 15, I32_SWAR});) 125 DEF_BENCH(return (new SkVMBench{ 63, I32_SWAR});) 126 DEF_BENCH(return (new SkVMBench{ 256, I32_SWAR});) 127 DEF_BENCH(return (new SkVMBench{1024, I32_SWAR});) 128 DEF_BENCH(return (new SkVMBench{4096, I32_SWAR});) 129 130 class SkVM_Overhead : public Benchmark { 131 public: SkVM_Overhead(bool rp)132 explicit SkVM_Overhead(bool rp) : fRP(rp) {} 133 134 private: onGetName()135 const char* onGetName() override { return fRP ? "SkVM_Overhead_RP" : "SkVM_Overhead_VM"; } isSuitableFor(Backend backend)136 bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; } 137 onDraw(int loops,SkCanvas *)138 void onDraw(int loops, SkCanvas*) override { 139 float dummy; 140 if (fRP) { 141 while (loops --> 0) { 142 SkRasterPipeline_<256> rp; 143 SkRasterPipeline_MemoryCtx src = { &dummy, 0}, 144 dst = { &dummy, 0}; 145 rp.append_load (SkColorType::kRGBA_F32_SkColorType, &src); 146 rp.append_load_dst(SkColorType::kRGBA_F32_SkColorType, &dst); 147 rp.append (SkRasterPipeline::srcover); 148 rp.append_store (SkColorType::kRGBA_F32_SkColorType, &dst); 149 150 (void)rp.compile(); 151 } 152 } else { 153 while (loops --> 0) { 154 skvm::Program program = SrcoverBuilder_F32{}.done(); 155 program.eval(0, &dummy, &dummy); 156 } 157 } 158 } 159 160 bool fRP; 161 }; 162 DEF_BENCH(return new SkVM_Overhead{ true};) 163 DEF_BENCH(return new SkVM_Overhead{false};) 164