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