1 /* 2 * Copyright 2015 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 "SkColorPriv.h" 10 #include "SkMatrix.h" 11 #include "SkPaint.h" 12 #include "SkRandom.h" 13 #include "SkString.h" 14 15 #define TILE(x, width) (((x) & 0xFFFF) * width >> 16) 16 17 class InterpBench : public Benchmark { 18 enum { 19 kBuffer = 128, 20 kLoop = 20000 21 }; 22 SkString fName; 23 int16_t fDst[kBuffer]; 24 float fFx, fDx; 25 public: InterpBench(const char name[])26 InterpBench(const char name[]) { 27 fName.printf("interp_%s", name); 28 fFx = 3.3f; 29 fDx = 0.1257f; 30 } 31 isSuitableFor(Backend backend)32 bool isSuitableFor(Backend backend) override { 33 return backend == kNonRendering_Backend; 34 } 35 36 virtual void performTest(int16_t dst[], float x, float dx, int count) = 0; 37 38 protected: mulLoopCount() const39 virtual int mulLoopCount() const { return 1; } 40 onGetName()41 const char* onGetName() override { 42 return fName.c_str(); 43 } 44 onDraw(int loops,SkCanvas *)45 void onDraw(int loops, SkCanvas*) override { 46 int n = loops * this->mulLoopCount(); 47 for (int i = 0; i < n; i++) { 48 this->performTest(fDst, fFx, fDx, kBuffer); 49 } 50 } 51 52 private: 53 typedef Benchmark INHERITED; 54 }; 55 56 class Fixed16D16Interp : public InterpBench { 57 public: Fixed16D16Interp()58 Fixed16D16Interp() : INHERITED("16.16") {} 59 60 protected: performTest(int16_t dst[],float fx,float dx,int count)61 void performTest(int16_t dst[], float fx, float dx, int count) override { 62 SkFixed curr = SkFloatToFixed(fx); 63 SkFixed step = SkFloatToFixed(dx); 64 for (int i = 0; i < count; i += 4) { 65 dst[i + 0] = TILE(curr, count); curr += step; 66 dst[i + 1] = TILE(curr, count); curr += step; 67 dst[i + 2] = TILE(curr, count); curr += step; 68 dst[i + 3] = TILE(curr, count); curr += step; 69 } 70 } 71 private: 72 typedef InterpBench INHERITED; 73 }; 74 75 class Fixed32D32Interp : public InterpBench { 76 public: Fixed32D32Interp()77 Fixed32D32Interp() : INHERITED("32.32") {} 78 79 protected: performTest(int16_t dst[],float fx,float dx,int count)80 void performTest(int16_t dst[], float fx, float dx, int count) override { 81 int64_t curr = (int64_t)(fx * 65536 * 655536); 82 int64_t step = (int64_t)(dx * 65536 * 655536); 83 SkFixed tmp; 84 for (int i = 0; i < count; i += 4) { 85 tmp = (SkFixed)(curr >> 16); 86 dst[i + 0] = TILE(tmp, count); 87 curr += step; 88 89 tmp = (SkFixed)(curr >> 16); 90 dst[i + 1] = TILE(tmp, count); 91 curr += step; 92 93 tmp = (SkFixed)(curr >> 16); 94 dst[i + 2] = TILE(tmp, count); 95 curr += step; 96 97 tmp = (SkFixed)(curr >> 16); 98 dst[i + 3] = TILE(tmp, count); 99 curr += step; 100 } 101 } 102 private: 103 typedef InterpBench INHERITED; 104 }; 105 106 class Fixed16D48Interp : public InterpBench { 107 public: Fixed16D48Interp()108 Fixed16D48Interp() : INHERITED("16.48") {} 109 110 protected: performTest(int16_t dst[],float fx,float dx,int count)111 void performTest(int16_t dst[], float fx, float dx, int count) override { 112 int64_t curr = (int64_t)(fx * 65536 * 655536 * 65536); 113 int64_t step = (int64_t)(dx * 65536 * 655536 * 65536); 114 SkFixed tmp; 115 for (int i = 0; i < count; i += 4) { 116 tmp = (SkFixed) (curr >> 32); dst[i + 0] = TILE(tmp, count); curr += step; 117 tmp = (SkFixed) (curr >> 32); dst[i + 1] = TILE(tmp, count); curr += step; 118 tmp = (SkFixed) (curr >> 32); dst[i + 2] = TILE(tmp, count); curr += step; 119 tmp = (SkFixed) (curr >> 32); dst[i + 3] = TILE(tmp, count); curr += step; 120 } 121 } 122 private: 123 typedef InterpBench INHERITED; 124 }; 125 126 class FloatInterp : public InterpBench { 127 public: FloatInterp()128 FloatInterp() : INHERITED("float") {} 129 130 protected: performTest(int16_t dst[],float fx,float dx,int count)131 void performTest(int16_t dst[], float fx, float dx, int count) override { 132 SkFixed tmp; 133 for (int i = 0; i < count; i += 4) { 134 tmp = SkFloatToFixed(fx); dst[i + 0] = TILE(tmp, count); fx += dx; 135 tmp = SkFloatToFixed(fx); dst[i + 1] = TILE(tmp, count); fx += dx; 136 tmp = SkFloatToFixed(fx); dst[i + 2] = TILE(tmp, count); fx += dx; 137 tmp = SkFloatToFixed(fx); dst[i + 3] = TILE(tmp, count); fx += dx; 138 } 139 } 140 private: 141 typedef InterpBench INHERITED; 142 }; 143 144 class DoubleInterp : public InterpBench { 145 public: DoubleInterp()146 DoubleInterp() : INHERITED("double") {} 147 148 protected: performTest(int16_t dst[],float fx,float dx,int count)149 void performTest(int16_t dst[], float fx, float dx, int count) override { 150 double ffx = fx; 151 double ddx = dx; 152 SkFixed tmp; 153 for (int i = 0; i < count; i += 4) { 154 tmp = SkDoubleToFixed(ffx); dst[i + 0] = TILE(tmp, count); ffx += ddx; 155 tmp = SkDoubleToFixed(ffx); dst[i + 1] = TILE(tmp, count); ffx += ddx; 156 tmp = SkDoubleToFixed(ffx); dst[i + 2] = TILE(tmp, count); ffx += ddx; 157 tmp = SkDoubleToFixed(ffx); dst[i + 3] = TILE(tmp, count); ffx += ddx; 158 } 159 } 160 private: 161 typedef InterpBench INHERITED; 162 }; 163 164 /////////////////////////////////////////////////////////////////////////////// 165 166 DEF_BENCH( return new Fixed16D16Interp(); ) 167 DEF_BENCH( return new Fixed32D32Interp(); ) 168 DEF_BENCH( return new Fixed16D48Interp(); ) 169 DEF_BENCH( return new FloatInterp(); ) 170 DEF_BENCH( return new DoubleInterp(); ) 171