blob: a5cc033c6fc63f72c9d4f707da1a69533190413f [file] [log] [blame]
mtkleinf0599002015-07-13 06:18:39 -07001/*
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
tfarinaf168b862014-06-19 12:32:29 -07008#include "Benchmark.h"
reed@google.come05cc8e2011-10-10 14:19:40 +00009#include "SkColorPriv.h"
reed@google.comddc518b2011-08-29 17:49:23 +000010#include "SkMatrix.h"
tfarinaf168b862014-06-19 12:32:29 -070011#include "SkPaint.h"
reed@google.comddc518b2011-08-29 17:49:23 +000012#include "SkRandom.h"
13#include "SkString.h"
14
reed@google.com7f192412012-05-30 12:26:52 +000015static float sk_fsel(float pred, float result_ge, float result_lt) {
16 return pred >= 0 ? result_ge : result_lt;
17}
18
19static float fast_floor(float x) {
reed@google.comf3a8d8e2012-05-30 14:08:57 +000020// float big = sk_fsel(x, 0x1.0p+23, -0x1.0p+23);
21 float big = sk_fsel(x, (float)(1 << 23), -(float)(1 << 23));
reed@google.com7f192412012-05-30 12:26:52 +000022 return (x + big) - big;
23}
24
tfarinaf168b862014-06-19 12:32:29 -070025class MathBench : public Benchmark {
reed@google.comddc518b2011-08-29 17:49:23 +000026 enum {
27 kBuffer = 100,
reed@google.comddc518b2011-08-29 17:49:23 +000028 };
29 SkString fName;
30 float fSrc[kBuffer], fDst[kBuffer];
31public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000032 MathBench(const char name[]) {
reed@google.comddc518b2011-08-29 17:49:23 +000033 fName.printf("math_%s", name);
34
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000035 SkRandom rand;
reed@google.comddc518b2011-08-29 17:49:23 +000036 for (int i = 0; i < kBuffer; ++i) {
37 fSrc[i] = rand.nextSScalar1();
38 }
commit-bot@chromium.org644629c2013-11-21 06:21:58 +000039 }
tomhudson@google.com9dc27132012-09-13 15:50:24 +000040
mtklein36352bf2015-03-25 18:17:31 -070041 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +000042 return backend == kNonRendering_Backend;
reed@google.comddc518b2011-08-29 17:49:23 +000043 }
44
rmistry@google.comfbfcd562012-08-23 18:09:54 +000045 virtual void performTest(float* SK_RESTRICT dst,
46 const float* SK_RESTRICT src,
robertphillips@google.com6853e802012-04-16 15:50:18 +000047 int count) = 0;
reed@google.comddc518b2011-08-29 17:49:23 +000048
49protected:
50 virtual int mulLoopCount() const { return 1; }
51
mtkleinf0599002015-07-13 06:18:39 -070052 const char* onGetName() override {
reed@google.comddc518b2011-08-29 17:49:23 +000053 return fName.c_str();
54 }
55
mtkleina1ebeb22015-10-01 09:43:39 -070056 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +000057 int n = loops * this->mulLoopCount();
reed@google.comddc518b2011-08-29 17:49:23 +000058 for (int i = 0; i < n; i++) {
59 this->performTest(fDst, fSrc, kBuffer);
60 }
61 }
62
63private:
tfarinaf168b862014-06-19 12:32:29 -070064 typedef Benchmark INHERITED;
reed@google.comddc518b2011-08-29 17:49:23 +000065};
66
reed@google.come05cc8e2011-10-10 14:19:40 +000067class MathBenchU32 : public MathBench {
68public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000069 MathBenchU32(const char name[]) : INHERITED(name) {}
skia.committer@gmail.com81521132013-04-30 07:01:03 +000070
reed@google.come05cc8e2011-10-10 14:19:40 +000071protected:
rmistry@google.comfbfcd562012-08-23 18:09:54 +000072 virtual void performITest(uint32_t* SK_RESTRICT dst,
73 const uint32_t* SK_RESTRICT src,
robertphillips@google.com6853e802012-04-16 15:50:18 +000074 int count) = 0;
skia.committer@gmail.com81521132013-04-30 07:01:03 +000075
mtkleinf0599002015-07-13 06:18:39 -070076 void performTest(float* SK_RESTRICT dst, const float* SK_RESTRICT src, int count) override {
reed@google.come05cc8e2011-10-10 14:19:40 +000077 uint32_t* d = SkTCast<uint32_t*>(dst);
78 const uint32_t* s = SkTCast<const uint32_t*>(src);
79 this->performITest(d, s, count);
80 }
81private:
82 typedef MathBench INHERITED;
83};
84
85///////////////////////////////////////////////////////////////////////////////
reed@google.comddc518b2011-08-29 17:49:23 +000086
87class NoOpMathBench : public MathBench {
88public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000089 NoOpMathBench() : INHERITED("noOp") {}
reed@google.comddc518b2011-08-29 17:49:23 +000090protected:
mtkleinf0599002015-07-13 06:18:39 -070091 void performTest(float* SK_RESTRICT dst, const float* SK_RESTRICT src, int count) override {
reed@google.comddc518b2011-08-29 17:49:23 +000092 for (int i = 0; i < count; ++i) {
93 dst[i] = src[i] + 1;
94 }
95 }
96private:
97 typedef MathBench INHERITED;
98};
99
commit-bot@chromium.org11e5b972013-11-08 20:14:16 +0000100class SkRSqrtMathBench : public MathBench {
101public:
102 SkRSqrtMathBench() : INHERITED("sk_float_rsqrt") {}
103protected:
mtkleinf0599002015-07-13 06:18:39 -0700104 void performTest(float* SK_RESTRICT dst, const float* SK_RESTRICT src, int count) override {
commit-bot@chromium.org11e5b972013-11-08 20:14:16 +0000105 for (int i = 0; i < count; ++i) {
106 dst[i] = sk_float_rsqrt(src[i]);
107 }
108 }
109private:
110 typedef MathBench INHERITED;
111};
112
113
robertphillips@google.com36bb2702013-08-12 12:02:28 +0000114class SlowISqrtMathBench : public MathBench {
reed@google.comddc518b2011-08-29 17:49:23 +0000115public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000116 SlowISqrtMathBench() : INHERITED("slowIsqrt") {}
commit-bot@chromium.orgb3ecdc42013-08-12 08:37:51 +0000117protected:
mtkleinf0599002015-07-13 06:18:39 -0700118 void performTest(float* SK_RESTRICT dst, const float* SK_RESTRICT src, int count) override {
robertphillips@google.com36bb2702013-08-12 12:02:28 +0000119 for (int i = 0; i < count; ++i) {
120 dst[i] = 1.0f / sk_float_sqrt(src[i]);
commit-bot@chromium.orgb3ecdc42013-08-12 08:37:51 +0000121 }
commit-bot@chromium.orgb3ecdc42013-08-12 08:37:51 +0000122 }
reed@google.comddc518b2011-08-29 17:49:23 +0000123private:
robertphillips@google.com36bb2702013-08-12 12:02:28 +0000124 typedef MathBench INHERITED;
125};
126
127static inline float SkFastInvSqrt(float x) {
128 float xhalf = 0.5f*x;
129 int i = *SkTCast<int*>(&x);
130 i = 0x5f3759df - (i>>1);
131 x = *SkTCast<float*>(&i);
132 x = x*(1.5f-xhalf*x*x);
133// x = x*(1.5f-xhalf*x*x); // this line takes err from 10^-3 to 10^-6
134 return x;
135}
136
137class FastISqrtMathBench : public MathBench {
138public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000139 FastISqrtMathBench() : INHERITED("fastIsqrt") {}
robertphillips@google.com36bb2702013-08-12 12:02:28 +0000140protected:
mtkleinf0599002015-07-13 06:18:39 -0700141 void performTest(float* SK_RESTRICT dst, const float* SK_RESTRICT src, int count) override {
robertphillips@google.com36bb2702013-08-12 12:02:28 +0000142 for (int i = 0; i < count; ++i) {
143 dst[i] = SkFastInvSqrt(src[i]);
144 }
145 }
146private:
147 typedef MathBench INHERITED;
reed@google.comddc518b2011-08-29 17:49:23 +0000148};
149
reed@google.come05cc8e2011-10-10 14:19:40 +0000150static inline uint32_t QMul64(uint32_t value, U8CPU alpha) {
151 SkASSERT((uint8_t)alpha == alpha);
152 const uint32_t mask = 0xFF00FF;
153
154 uint64_t tmp = value;
155 tmp = (tmp & mask) | ((tmp & ~mask) << 24);
156 tmp *= alpha;
caryclark@google.com19069a22012-06-06 12:11:45 +0000157 return (uint32_t) (((tmp >> 8) & mask) | ((tmp >> 32) & ~mask));
reed@google.come05cc8e2011-10-10 14:19:40 +0000158}
159
160class QMul64Bench : public MathBenchU32 {
161public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000162 QMul64Bench() : INHERITED("qmul64") {}
reed@google.come05cc8e2011-10-10 14:19:40 +0000163protected:
mtkleinf0599002015-07-13 06:18:39 -0700164 void performITest(uint32_t* SK_RESTRICT dst,
165 const uint32_t* SK_RESTRICT src,
166 int count) override {
reed@google.come05cc8e2011-10-10 14:19:40 +0000167 for (int i = 0; i < count; ++i) {
168 dst[i] = QMul64(src[i], (uint8_t)i);
169 }
170 }
171private:
172 typedef MathBenchU32 INHERITED;
173};
174
175class QMul32Bench : public MathBenchU32 {
176public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000177 QMul32Bench() : INHERITED("qmul32") {}
reed@google.come05cc8e2011-10-10 14:19:40 +0000178protected:
mtkleinf0599002015-07-13 06:18:39 -0700179 void performITest(uint32_t* SK_RESTRICT dst,
180 const uint32_t* SK_RESTRICT src,
181 int count) override {
reed@google.come05cc8e2011-10-10 14:19:40 +0000182 for (int i = 0; i < count; ++i) {
183 dst[i] = SkAlphaMulQ(src[i], (uint8_t)i);
184 }
185 }
186private:
187 typedef MathBenchU32 INHERITED;
188};
189
reed@google.comddc518b2011-08-29 17:49:23 +0000190///////////////////////////////////////////////////////////////////////////////
191
reed@google.com0be5eb72011-12-05 21:53:22 +0000192static bool isFinite_int(float x) {
193 uint32_t bits = SkFloat2Bits(x); // need unsigned for our shifts
194 int exponent = bits << 1 >> 24;
195 return exponent != 0xFF;
196}
197
198static bool isFinite_float(float x) {
robertphillips@google.com6853e802012-04-16 15:50:18 +0000199 return SkToBool(sk_float_isfinite(x));
reed@google.com0be5eb72011-12-05 21:53:22 +0000200}
201
202static bool isFinite_mulzero(float x) {
203 float y = x * 0;
204 return y == y;
205}
206
207static bool isfinite_and_int(const float data[4]) {
208 return isFinite_int(data[0]) && isFinite_int(data[1]) && isFinite_int(data[2]) && isFinite_int(data[3]);
209}
210
211static bool isfinite_and_float(const float data[4]) {
212 return isFinite_float(data[0]) && isFinite_float(data[1]) && isFinite_float(data[2]) && isFinite_float(data[3]);
213}
214
215static bool isfinite_and_mulzero(const float data[4]) {
216 return isFinite_mulzero(data[0]) && isFinite_mulzero(data[1]) && isFinite_mulzero(data[2]) && isFinite_mulzero(data[3]);
217}
218
219#define mulzeroadd(data) (data[0]*0 + data[1]*0 + data[2]*0 + data[3]*0)
220
221static bool isfinite_plus_int(const float data[4]) {
222 return isFinite_int(mulzeroadd(data));
223}
224
225static bool isfinite_plus_float(const float data[4]) {
reed@google.com5ae777d2011-12-06 20:18:05 +0000226 return !sk_float_isnan(mulzeroadd(data));
reed@google.com0be5eb72011-12-05 21:53:22 +0000227}
228
229static bool isfinite_plus_mulzero(const float data[4]) {
230 float x = mulzeroadd(data);
231 return x == x;
232}
233
234typedef bool (*IsFiniteProc)(const float[]);
235
236#define MAKEREC(name) { name, #name }
237
238static const struct {
239 IsFiniteProc fProc;
240 const char* fName;
241} gRec[] = {
242 MAKEREC(isfinite_and_int),
243 MAKEREC(isfinite_and_float),
244 MAKEREC(isfinite_and_mulzero),
245 MAKEREC(isfinite_plus_int),
246 MAKEREC(isfinite_plus_float),
247 MAKEREC(isfinite_plus_mulzero),
248};
249
250#undef MAKEREC
251
reed@google.com16078632011-12-06 18:56:37 +0000252static bool isFinite(const SkRect& r) {
253 // x * 0 will be NaN iff x is infinity or NaN.
254 // a + b will be NaN iff either a or b is NaN.
255 float value = r.fLeft * 0 + r.fTop * 0 + r.fRight * 0 + r.fBottom * 0;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000256
reed@google.com16078632011-12-06 18:56:37 +0000257 // value is either NaN or it is finite (zero).
258 // value==value will be true iff value is not NaN
259 return value == value;
260}
261
tfarinaf168b862014-06-19 12:32:29 -0700262class IsFiniteBench : public Benchmark {
reed@google.com0be5eb72011-12-05 21:53:22 +0000263 enum {
mtklein@google.comc2897432013-09-10 19:23:38 +0000264 N = 1000,
reed@google.com0be5eb72011-12-05 21:53:22 +0000265 };
266 float fData[N];
267public:
268
mtklein@google.com410e6e82013-09-13 19:52:27 +0000269 IsFiniteBench(int index) {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000270 SkRandom rand;
reed@google.com0be5eb72011-12-05 21:53:22 +0000271
272 for (int i = 0; i < N; ++i) {
273 fData[i] = rand.nextSScalar1();
274 }
reed@google.com16078632011-12-06 18:56:37 +0000275
276 if (index < 0) {
halcanary96fcdcc2015-08-27 07:41:13 -0700277 fProc = nullptr;
reed@google.com16078632011-12-06 18:56:37 +0000278 fName = "isfinite_rect";
279 } else {
280 fProc = gRec[index].fProc;
281 fName = gRec[index].fName;
282 }
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000283 }
284
mtklein36352bf2015-03-25 18:17:31 -0700285 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000286 return backend == kNonRendering_Backend;
reed@google.com0be5eb72011-12-05 21:53:22 +0000287 }
288
289protected:
mtkleina1ebeb22015-10-01 09:43:39 -0700290 void onDraw(int loops, SkCanvas*) override {
reed@google.com0be5eb72011-12-05 21:53:22 +0000291 IsFiniteProc proc = fProc;
292 const float* data = fData;
reed@google.com16078632011-12-06 18:56:37 +0000293 // do this so the compiler won't throw away the function call
294 int counter = 0;
reed@google.com0be5eb72011-12-05 21:53:22 +0000295
reed@google.com16078632011-12-06 18:56:37 +0000296 if (proc) {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000297 for (int j = 0; j < loops; ++j) {
reed@google.com16078632011-12-06 18:56:37 +0000298 for (int i = 0; i < N - 4; ++i) {
299 counter += proc(&data[i]);
300 }
reed@google.com0be5eb72011-12-05 21:53:22 +0000301 }
reed@google.com16078632011-12-06 18:56:37 +0000302 } else {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000303 for (int j = 0; j < loops; ++j) {
reed@google.com16078632011-12-06 18:56:37 +0000304 for (int i = 0; i < N - 4; ++i) {
305 const SkRect* r = reinterpret_cast<const SkRect*>(&data[i]);
caryclark@google.com19069a22012-06-06 12:11:45 +0000306 if (false) { // avoid bit rot, suppress warning
307 isFinite(*r);
308 }
reed@google.com16078632011-12-06 18:56:37 +0000309 counter += r->isFinite();
310 }
311 }
312 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000313
reed@google.com16078632011-12-06 18:56:37 +0000314 SkPaint paint;
315 if (paint.getAlpha() == 0) {
316 SkDebugf("%d\n", counter);
reed@google.com0be5eb72011-12-05 21:53:22 +0000317 }
318 }
319
mtkleinf0599002015-07-13 06:18:39 -0700320 const char* onGetName() override {
reed@google.com0be5eb72011-12-05 21:53:22 +0000321 return fName;
322 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000323
reed@google.com0be5eb72011-12-05 21:53:22 +0000324private:
325 IsFiniteProc fProc;
326 const char* fName;
327
tfarinaf168b862014-06-19 12:32:29 -0700328 typedef Benchmark INHERITED;
reed@google.com0be5eb72011-12-05 21:53:22 +0000329};
330
tfarinaf168b862014-06-19 12:32:29 -0700331class FloorBench : public Benchmark {
reed@google.com7f192412012-05-30 12:26:52 +0000332 enum {
mtklein@google.comc2897432013-09-10 19:23:38 +0000333 ARRAY = 1000,
reed@google.com7f192412012-05-30 12:26:52 +0000334 };
335 float fData[ARRAY];
336 bool fFast;
337public:
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000338
mtklein@google.com410e6e82013-09-13 19:52:27 +0000339 FloorBench(bool fast) : fFast(fast) {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000340 SkRandom rand;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000341
reed@google.com7f192412012-05-30 12:26:52 +0000342 for (int i = 0; i < ARRAY; ++i) {
343 fData[i] = rand.nextSScalar1();
344 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000345
reed@google.com7f192412012-05-30 12:26:52 +0000346 if (fast) {
347 fName = "floor_fast";
348 } else {
349 fName = "floor_std";
350 }
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000351 }
352
mtklein36352bf2015-03-25 18:17:31 -0700353 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000354 return backend == kNonRendering_Backend;
reed@google.com7f192412012-05-30 12:26:52 +0000355 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000356
reed@google.com7f192412012-05-30 12:26:52 +0000357 virtual void process(float) {}
358
359protected:
mtkleina1ebeb22015-10-01 09:43:39 -0700360 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000361 SkRandom rand;
reed@google.com7f192412012-05-30 12:26:52 +0000362 float accum = 0;
363 const float* data = fData;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000364
reed@google.com7f192412012-05-30 12:26:52 +0000365 if (fFast) {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000366 for (int j = 0; j < loops; ++j) {
reed@google.com7f192412012-05-30 12:26:52 +0000367 for (int i = 0; i < ARRAY; ++i) {
368 accum += fast_floor(data[i]);
369 }
370 this->process(accum);
371 }
372 } else {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000373 for (int j = 0; j < loops; ++j) {
reed@google.com7f192412012-05-30 12:26:52 +0000374 for (int i = 0; i < ARRAY; ++i) {
375 accum += sk_float_floor(data[i]);
376 }
377 this->process(accum);
378 }
379 }
380 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000381
mtkleinf0599002015-07-13 06:18:39 -0700382 const char* onGetName() override {
reed@google.com7f192412012-05-30 12:26:52 +0000383 return fName;
384 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000385
reed@google.com7f192412012-05-30 12:26:52 +0000386private:
387 const char* fName;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000388
tfarinaf168b862014-06-19 12:32:29 -0700389 typedef Benchmark INHERITED;
reed@google.com7f192412012-05-30 12:26:52 +0000390};
391
tfarinaf168b862014-06-19 12:32:29 -0700392class CLZBench : public Benchmark {
reed@google.com0d7aac92013-04-29 13:55:11 +0000393 enum {
mtklein@google.comc2897432013-09-10 19:23:38 +0000394 ARRAY = 1000,
reed@google.com0d7aac92013-04-29 13:55:11 +0000395 };
396 uint32_t fData[ARRAY];
397 bool fUsePortable;
398
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000399public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000400 CLZBench(bool usePortable) : fUsePortable(usePortable) {
reed@google.com0d7aac92013-04-29 13:55:11 +0000401
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000402 SkRandom rand;
reed@google.com0d7aac92013-04-29 13:55:11 +0000403 for (int i = 0; i < ARRAY; ++i) {
404 fData[i] = rand.nextU();
405 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000406
reed@google.com0d7aac92013-04-29 13:55:11 +0000407 if (fUsePortable) {
408 fName = "clz_portable";
409 } else {
410 fName = "clz_intrinsic";
411 }
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000412 }
413
mtklein36352bf2015-03-25 18:17:31 -0700414 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000415 return backend == kNonRendering_Backend;
reed@google.com0d7aac92013-04-29 13:55:11 +0000416 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000417
reed@google.com0d7aac92013-04-29 13:55:11 +0000418 // just so the compiler doesn't remove our loops
419 virtual void process(int) {}
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000420
reed@google.com0d7aac92013-04-29 13:55:11 +0000421protected:
mtkleina1ebeb22015-10-01 09:43:39 -0700422 void onDraw(int loops, SkCanvas*) override {
reed@google.com0d7aac92013-04-29 13:55:11 +0000423 int accum = 0;
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000424
reed@google.com0d7aac92013-04-29 13:55:11 +0000425 if (fUsePortable) {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000426 for (int j = 0; j < loops; ++j) {
reed@google.com0d7aac92013-04-29 13:55:11 +0000427 for (int i = 0; i < ARRAY; ++i) {
428 accum += SkCLZ_portable(fData[i]);
429 }
430 this->process(accum);
431 }
432 } else {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000433 for (int j = 0; j < loops; ++j) {
reed@google.com0d7aac92013-04-29 13:55:11 +0000434 for (int i = 0; i < ARRAY; ++i) {
435 accum += SkCLZ(fData[i]);
436 }
437 this->process(accum);
438 }
439 }
440 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000441
mtkleinf0599002015-07-13 06:18:39 -0700442 const char* onGetName() override {
reed@google.com0d7aac92013-04-29 13:55:11 +0000443 return fName;
444 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000445
reed@google.com0d7aac92013-04-29 13:55:11 +0000446private:
447 const char* fName;
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000448
tfarinaf168b862014-06-19 12:32:29 -0700449 typedef Benchmark INHERITED;
reed@google.com0d7aac92013-04-29 13:55:11 +0000450};
451
reed@google.com0be5eb72011-12-05 21:53:22 +0000452///////////////////////////////////////////////////////////////////////////////
453
tfarinaf168b862014-06-19 12:32:29 -0700454class NormalizeBench : public Benchmark {
reed@google.com0889f682013-05-03 12:56:39 +0000455 enum {
mtklein@google.comc2897432013-09-10 19:23:38 +0000456 ARRAY =1000,
reed@google.com0889f682013-05-03 12:56:39 +0000457 };
458 SkVector fVec[ARRAY];
skia.committer@gmail.comecc9d282013-05-04 07:01:15 +0000459
reed@google.com0889f682013-05-03 12:56:39 +0000460public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000461 NormalizeBench() {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000462 SkRandom rand;
reed@google.com0889f682013-05-03 12:56:39 +0000463 for (int i = 0; i < ARRAY; ++i) {
464 fVec[i].set(rand.nextSScalar1(), rand.nextSScalar1());
465 }
skia.committer@gmail.comecc9d282013-05-04 07:01:15 +0000466
reed@google.com0889f682013-05-03 12:56:39 +0000467 fName = "point_normalize";
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000468 }
469
mtklein36352bf2015-03-25 18:17:31 -0700470 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000471 return backend == kNonRendering_Backend;
reed@google.com0889f682013-05-03 12:56:39 +0000472 }
skia.committer@gmail.comecc9d282013-05-04 07:01:15 +0000473
reed@google.com0889f682013-05-03 12:56:39 +0000474 // just so the compiler doesn't remove our loops
475 virtual void process(int) {}
skia.committer@gmail.comecc9d282013-05-04 07:01:15 +0000476
reed@google.com0889f682013-05-03 12:56:39 +0000477protected:
mtkleina1ebeb22015-10-01 09:43:39 -0700478 void onDraw(int loops, SkCanvas*) override {
reed@google.com0889f682013-05-03 12:56:39 +0000479 int accum = 0;
skia.committer@gmail.comecc9d282013-05-04 07:01:15 +0000480
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000481 for (int j = 0; j < loops; ++j) {
reed@google.com0889f682013-05-03 12:56:39 +0000482 for (int i = 0; i < ARRAY; ++i) {
483 accum += fVec[i].normalize();
484 }
485 this->process(accum);
486 }
487 }
skia.committer@gmail.comecc9d282013-05-04 07:01:15 +0000488
mtkleinf0599002015-07-13 06:18:39 -0700489 const char* onGetName() override {
reed@google.com0889f682013-05-03 12:56:39 +0000490 return fName;
491 }
skia.committer@gmail.comecc9d282013-05-04 07:01:15 +0000492
reed@google.com0889f682013-05-03 12:56:39 +0000493private:
494 const char* fName;
skia.committer@gmail.comecc9d282013-05-04 07:01:15 +0000495
tfarinaf168b862014-06-19 12:32:29 -0700496 typedef Benchmark INHERITED;
reed@google.com0889f682013-05-03 12:56:39 +0000497};
498
499///////////////////////////////////////////////////////////////////////////////
500
tfarinaf168b862014-06-19 12:32:29 -0700501class FixedMathBench : public Benchmark {
djsollen@google.com25a11e42013-07-18 19:11:30 +0000502 enum {
mtklein@google.comc2897432013-09-10 19:23:38 +0000503 N = 1000,
djsollen@google.com25a11e42013-07-18 19:11:30 +0000504 };
505 float fData[N];
506 SkFixed fResult[N];
507public:
508
mtklein@google.com410e6e82013-09-13 19:52:27 +0000509 FixedMathBench() {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000510 SkRandom rand;
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000511 for (int i = 0; i < N; ++i) {
512 fData[i] = rand.nextSScalar1();
djsollen@google.com25a11e42013-07-18 19:11:30 +0000513 }
514
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000515 }
516
mtklein36352bf2015-03-25 18:17:31 -0700517 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000518 return backend == kNonRendering_Backend;
djsollen@google.com25a11e42013-07-18 19:11:30 +0000519 }
520
521protected:
mtkleina1ebeb22015-10-01 09:43:39 -0700522 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000523 for (int j = 0; j < loops; ++j) {
djsollen@google.com25a11e42013-07-18 19:11:30 +0000524 for (int i = 0; i < N - 4; ++i) {
525 fResult[i] = SkFloatToFixed(fData[i]);
526 }
527 }
528
529 SkPaint paint;
530 if (paint.getAlpha() == 0) {
531 SkDebugf("%d\n", fResult[0]);
532 }
533 }
534
mtkleinf0599002015-07-13 06:18:39 -0700535 const char* onGetName() override {
djsollen@google.com25a11e42013-07-18 19:11:30 +0000536 return "float_to_fixed";
537 }
538
539private:
tfarinaf168b862014-06-19 12:32:29 -0700540 typedef Benchmark INHERITED;
djsollen@google.com25a11e42013-07-18 19:11:30 +0000541};
542
543///////////////////////////////////////////////////////////////////////////////
544
commit-bot@chromium.org2c86fbb2013-09-26 19:22:54 +0000545template <typename T>
tfarinaf168b862014-06-19 12:32:29 -0700546class DivModBench : public Benchmark {
mtklein@google.com9cb51772013-09-27 13:39:14 +0000547 SkString fName;
commit-bot@chromium.org2c86fbb2013-09-26 19:22:54 +0000548public:
mtklein@google.com9cb51772013-09-27 13:39:14 +0000549 explicit DivModBench(const char* name) {
550 fName.printf("divmod_%s", name);
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000551 }
552
mtklein36352bf2015-03-25 18:17:31 -0700553 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000554 return backend == kNonRendering_Backend;
commit-bot@chromium.org2c86fbb2013-09-26 19:22:54 +0000555 }
556
557protected:
mtkleinf0599002015-07-13 06:18:39 -0700558 const char* onGetName() override {
mtklein@google.com9cb51772013-09-27 13:39:14 +0000559 return fName.c_str();
commit-bot@chromium.org2c86fbb2013-09-26 19:22:54 +0000560 }
561
mtkleina1ebeb22015-10-01 09:43:39 -0700562 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org2c86fbb2013-09-26 19:22:54 +0000563 volatile T a = 0, b = 0;
564 T div = 0, mod = 0;
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000565 for (int i = 0; i < loops; i++) {
commit-bot@chromium.org2c86fbb2013-09-26 19:22:54 +0000566 if ((T)i == 0) continue; // Small T will wrap around.
567 SkTDivMod((T)(i+1), (T)i, &div, &mod);
568 a ^= div;
569 b ^= mod;
570 }
571 }
572};
573DEF_BENCH(return new DivModBench<uint8_t>("uint8_t"))
574DEF_BENCH(return new DivModBench<uint16_t>("uint16_t"))
575DEF_BENCH(return new DivModBench<uint32_t>("uint32_t"))
576DEF_BENCH(return new DivModBench<uint64_t>("uint64_t"))
577
578DEF_BENCH(return new DivModBench<int8_t>("int8_t"))
579DEF_BENCH(return new DivModBench<int16_t>("int16_t"))
580DEF_BENCH(return new DivModBench<int32_t>("int32_t"))
581DEF_BENCH(return new DivModBench<int64_t>("int64_t"))
582
583///////////////////////////////////////////////////////////////////////////////
584
mtklein@google.com410e6e82013-09-13 19:52:27 +0000585DEF_BENCH( return new NoOpMathBench(); )
commit-bot@chromium.org11e5b972013-11-08 20:14:16 +0000586DEF_BENCH( return new SkRSqrtMathBench(); )
mtklein@google.com410e6e82013-09-13 19:52:27 +0000587DEF_BENCH( return new SlowISqrtMathBench(); )
588DEF_BENCH( return new FastISqrtMathBench(); )
589DEF_BENCH( return new QMul64Bench(); )
590DEF_BENCH( return new QMul32Bench(); )
reed@google.comddc518b2011-08-29 17:49:23 +0000591
mtklein@google.com410e6e82013-09-13 19:52:27 +0000592DEF_BENCH( return new IsFiniteBench(-1); )
593DEF_BENCH( return new IsFiniteBench(0); )
594DEF_BENCH( return new IsFiniteBench(1); )
595DEF_BENCH( return new IsFiniteBench(2); )
596DEF_BENCH( return new IsFiniteBench(3); )
597DEF_BENCH( return new IsFiniteBench(4); )
598DEF_BENCH( return new IsFiniteBench(5); )
reed@google.com0be5eb72011-12-05 21:53:22 +0000599
mtklein@google.com410e6e82013-09-13 19:52:27 +0000600DEF_BENCH( return new FloorBench(false); )
601DEF_BENCH( return new FloorBench(true); )
reed@google.com7f192412012-05-30 12:26:52 +0000602
mtklein@google.com410e6e82013-09-13 19:52:27 +0000603DEF_BENCH( return new CLZBench(false); )
604DEF_BENCH( return new CLZBench(true); )
reed@google.com0889f682013-05-03 12:56:39 +0000605
mtklein@google.com410e6e82013-09-13 19:52:27 +0000606DEF_BENCH( return new NormalizeBench(); )
djsollen@google.com25a11e42013-07-18 19:11:30 +0000607
mtklein@google.com410e6e82013-09-13 19:52:27 +0000608DEF_BENCH( return new FixedMathBench(); )