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