xref: /aosp_15_r20/external/skia/bench/MathBench.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2015 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "bench/Benchmark.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMatrix.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/SkColorData.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkFixed.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkMathPriv.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkRandom.h"
16*c8dee2aaSAndroid Build Coastguard Worker 
sk_fsel(float pred,float result_ge,float result_lt)17*c8dee2aaSAndroid Build Coastguard Worker static float sk_fsel(float pred, float result_ge, float result_lt) {
18*c8dee2aaSAndroid Build Coastguard Worker     return pred >= 0 ? result_ge : result_lt;
19*c8dee2aaSAndroid Build Coastguard Worker }
20*c8dee2aaSAndroid Build Coastguard Worker 
fast_floor(float x)21*c8dee2aaSAndroid Build Coastguard Worker static float fast_floor(float x) {
22*c8dee2aaSAndroid Build Coastguard Worker //    float big = sk_fsel(x, 0x1.0p+23, -0x1.0p+23);
23*c8dee2aaSAndroid Build Coastguard Worker     float big = sk_fsel(x, (float)(1 << 23), -(float)(1 << 23));
24*c8dee2aaSAndroid Build Coastguard Worker     return (x + big) - big;
25*c8dee2aaSAndroid Build Coastguard Worker }
26*c8dee2aaSAndroid Build Coastguard Worker 
27*c8dee2aaSAndroid Build Coastguard Worker class MathBench : public Benchmark {
28*c8dee2aaSAndroid Build Coastguard Worker     enum {
29*c8dee2aaSAndroid Build Coastguard Worker         kBuffer = 100,
30*c8dee2aaSAndroid Build Coastguard Worker     };
31*c8dee2aaSAndroid Build Coastguard Worker     SkString    fName;
32*c8dee2aaSAndroid Build Coastguard Worker     float       fSrc[kBuffer], fDst[kBuffer];
33*c8dee2aaSAndroid Build Coastguard Worker public:
MathBench(const char name[])34*c8dee2aaSAndroid Build Coastguard Worker     MathBench(const char name[])  {
35*c8dee2aaSAndroid Build Coastguard Worker         fName.printf("math_%s", name);
36*c8dee2aaSAndroid Build Coastguard Worker 
37*c8dee2aaSAndroid Build Coastguard Worker         SkRandom rand;
38*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < kBuffer; ++i) {
39*c8dee2aaSAndroid Build Coastguard Worker             fSrc[i] = rand.nextSScalar1();
40*c8dee2aaSAndroid Build Coastguard Worker         }
41*c8dee2aaSAndroid Build Coastguard Worker     }
42*c8dee2aaSAndroid Build Coastguard Worker 
isSuitableFor(Backend backend)43*c8dee2aaSAndroid Build Coastguard Worker     bool isSuitableFor(Backend backend) override {
44*c8dee2aaSAndroid Build Coastguard Worker         return backend == Backend::kNonRendering;
45*c8dee2aaSAndroid Build Coastguard Worker     }
46*c8dee2aaSAndroid Build Coastguard Worker 
47*c8dee2aaSAndroid Build Coastguard Worker     virtual void performTest(float* SK_RESTRICT dst,
48*c8dee2aaSAndroid Build Coastguard Worker                               const float* SK_RESTRICT src,
49*c8dee2aaSAndroid Build Coastguard Worker                               int count) = 0;
50*c8dee2aaSAndroid Build Coastguard Worker 
51*c8dee2aaSAndroid Build Coastguard Worker protected:
mulLoopCount() const52*c8dee2aaSAndroid Build Coastguard Worker     virtual int mulLoopCount() const { return 1; }
53*c8dee2aaSAndroid Build Coastguard Worker 
onGetName()54*c8dee2aaSAndroid Build Coastguard Worker     const char* onGetName() override {
55*c8dee2aaSAndroid Build Coastguard Worker         return fName.c_str();
56*c8dee2aaSAndroid Build Coastguard Worker     }
57*c8dee2aaSAndroid Build Coastguard Worker 
onDraw(int loops,SkCanvas *)58*c8dee2aaSAndroid Build Coastguard Worker     void onDraw(int loops, SkCanvas*) override {
59*c8dee2aaSAndroid Build Coastguard Worker         int n = loops * this->mulLoopCount();
60*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < n; i++) {
61*c8dee2aaSAndroid Build Coastguard Worker             this->performTest(fDst, fSrc, kBuffer);
62*c8dee2aaSAndroid Build Coastguard Worker         }
63*c8dee2aaSAndroid Build Coastguard Worker     }
64*c8dee2aaSAndroid Build Coastguard Worker 
65*c8dee2aaSAndroid Build Coastguard Worker private:
66*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = Benchmark;
67*c8dee2aaSAndroid Build Coastguard Worker };
68*c8dee2aaSAndroid Build Coastguard Worker 
69*c8dee2aaSAndroid Build Coastguard Worker class MathBenchU32 : public MathBench {
70*c8dee2aaSAndroid Build Coastguard Worker public:
MathBenchU32(const char name[])71*c8dee2aaSAndroid Build Coastguard Worker     MathBenchU32(const char name[]) : INHERITED(name) {}
72*c8dee2aaSAndroid Build Coastguard Worker 
73*c8dee2aaSAndroid Build Coastguard Worker protected:
74*c8dee2aaSAndroid Build Coastguard Worker     virtual void performITest(uint32_t* SK_RESTRICT dst,
75*c8dee2aaSAndroid Build Coastguard Worker                               const uint32_t* SK_RESTRICT src,
76*c8dee2aaSAndroid Build Coastguard Worker                               int count) = 0;
77*c8dee2aaSAndroid Build Coastguard Worker 
performTest(float * SK_RESTRICT dst,const float * SK_RESTRICT src,int count)78*c8dee2aaSAndroid Build Coastguard Worker     void performTest(float* SK_RESTRICT dst, const float* SK_RESTRICT src, int count) override {
79*c8dee2aaSAndroid Build Coastguard Worker         uint32_t* d = reinterpret_cast<uint32_t*>(dst);
80*c8dee2aaSAndroid Build Coastguard Worker         const uint32_t* s = reinterpret_cast<const uint32_t*>(src);
81*c8dee2aaSAndroid Build Coastguard Worker         this->performITest(d, s, count);
82*c8dee2aaSAndroid Build Coastguard Worker     }
83*c8dee2aaSAndroid Build Coastguard Worker private:
84*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = MathBench;
85*c8dee2aaSAndroid Build Coastguard Worker };
86*c8dee2aaSAndroid Build Coastguard Worker 
87*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
88*c8dee2aaSAndroid Build Coastguard Worker 
89*c8dee2aaSAndroid Build Coastguard Worker class NoOpMathBench : public MathBench {
90*c8dee2aaSAndroid Build Coastguard Worker public:
NoOpMathBench()91*c8dee2aaSAndroid Build Coastguard Worker     NoOpMathBench() : INHERITED("noOp") {}
92*c8dee2aaSAndroid Build Coastguard Worker protected:
performTest(float * SK_RESTRICT dst,const float * SK_RESTRICT src,int count)93*c8dee2aaSAndroid Build Coastguard Worker     void performTest(float* SK_RESTRICT dst, const float* SK_RESTRICT src, int count) override {
94*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < count; ++i) {
95*c8dee2aaSAndroid Build Coastguard Worker             dst[i] = src[i] + 1;
96*c8dee2aaSAndroid Build Coastguard Worker         }
97*c8dee2aaSAndroid Build Coastguard Worker     }
98*c8dee2aaSAndroid Build Coastguard Worker private:
99*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = MathBench;
100*c8dee2aaSAndroid Build Coastguard Worker };
101*c8dee2aaSAndroid Build Coastguard Worker 
102*c8dee2aaSAndroid Build Coastguard Worker class SkRSqrtMathBench : public MathBench {
103*c8dee2aaSAndroid Build Coastguard Worker public:
SkRSqrtMathBench()104*c8dee2aaSAndroid Build Coastguard Worker     SkRSqrtMathBench() : INHERITED("sk_float_rsqrt") {}
105*c8dee2aaSAndroid Build Coastguard Worker protected:
performTest(float * SK_RESTRICT dst,const float * SK_RESTRICT src,int count)106*c8dee2aaSAndroid Build Coastguard Worker     void performTest(float* SK_RESTRICT dst, const float* SK_RESTRICT src, int count) override {
107*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < count; ++i) {
108*c8dee2aaSAndroid Build Coastguard Worker             dst[i] = sk_float_rsqrt(src[i]);
109*c8dee2aaSAndroid Build Coastguard Worker         }
110*c8dee2aaSAndroid Build Coastguard Worker     }
111*c8dee2aaSAndroid Build Coastguard Worker private:
112*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = MathBench;
113*c8dee2aaSAndroid Build Coastguard Worker };
114*c8dee2aaSAndroid Build Coastguard Worker 
115*c8dee2aaSAndroid Build Coastguard Worker 
116*c8dee2aaSAndroid Build Coastguard Worker class SlowISqrtMathBench : public MathBench {
117*c8dee2aaSAndroid Build Coastguard Worker public:
SlowISqrtMathBench()118*c8dee2aaSAndroid Build Coastguard Worker     SlowISqrtMathBench() : INHERITED("slowIsqrt") {}
119*c8dee2aaSAndroid Build Coastguard Worker protected:
performTest(float * SK_RESTRICT dst,const float * SK_RESTRICT src,int count)120*c8dee2aaSAndroid Build Coastguard Worker     void performTest(float* SK_RESTRICT dst, const float* SK_RESTRICT src, int count) override {
121*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < count; ++i) {
122*c8dee2aaSAndroid Build Coastguard Worker             dst[i] = 1.0f / std::sqrt(src[i]);
123*c8dee2aaSAndroid Build Coastguard Worker         }
124*c8dee2aaSAndroid Build Coastguard Worker     }
125*c8dee2aaSAndroid Build Coastguard Worker private:
126*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = MathBench;
127*c8dee2aaSAndroid Build Coastguard Worker };
128*c8dee2aaSAndroid Build Coastguard Worker 
129*c8dee2aaSAndroid Build Coastguard Worker class FastISqrtMathBench : public MathBench {
130*c8dee2aaSAndroid Build Coastguard Worker public:
FastISqrtMathBench()131*c8dee2aaSAndroid Build Coastguard Worker     FastISqrtMathBench() : INHERITED("fastIsqrt") {}
132*c8dee2aaSAndroid Build Coastguard Worker protected:
performTest(float * SK_RESTRICT dst,const float * SK_RESTRICT src,int count)133*c8dee2aaSAndroid Build Coastguard Worker     void performTest(float* SK_RESTRICT dst, const float* SK_RESTRICT src, int count) override {
134*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < count; ++i) {
135*c8dee2aaSAndroid Build Coastguard Worker             dst[i] = sk_float_rsqrt(src[i]);
136*c8dee2aaSAndroid Build Coastguard Worker         }
137*c8dee2aaSAndroid Build Coastguard Worker     }
138*c8dee2aaSAndroid Build Coastguard Worker private:
139*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = MathBench;
140*c8dee2aaSAndroid Build Coastguard Worker };
141*c8dee2aaSAndroid Build Coastguard Worker 
QMul64(uint32_t value,U8CPU alpha)142*c8dee2aaSAndroid Build Coastguard Worker static inline uint32_t QMul64(uint32_t value, U8CPU alpha) {
143*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT((uint8_t)alpha == alpha);
144*c8dee2aaSAndroid Build Coastguard Worker     const uint32_t mask = 0xFF00FF;
145*c8dee2aaSAndroid Build Coastguard Worker 
146*c8dee2aaSAndroid Build Coastguard Worker     uint64_t tmp = value;
147*c8dee2aaSAndroid Build Coastguard Worker     tmp = (tmp & mask) | ((tmp & ~mask) << 24);
148*c8dee2aaSAndroid Build Coastguard Worker     tmp *= alpha;
149*c8dee2aaSAndroid Build Coastguard Worker     return (uint32_t) (((tmp >> 8) & mask) | ((tmp >> 32) & ~mask));
150*c8dee2aaSAndroid Build Coastguard Worker }
151*c8dee2aaSAndroid Build Coastguard Worker 
152*c8dee2aaSAndroid Build Coastguard Worker class QMul64Bench : public MathBenchU32 {
153*c8dee2aaSAndroid Build Coastguard Worker public:
QMul64Bench()154*c8dee2aaSAndroid Build Coastguard Worker     QMul64Bench() : INHERITED("qmul64") {}
155*c8dee2aaSAndroid Build Coastguard Worker protected:
performITest(uint32_t * SK_RESTRICT dst,const uint32_t * SK_RESTRICT src,int count)156*c8dee2aaSAndroid Build Coastguard Worker     void performITest(uint32_t* SK_RESTRICT dst,
157*c8dee2aaSAndroid Build Coastguard Worker                       const uint32_t* SK_RESTRICT src,
158*c8dee2aaSAndroid Build Coastguard Worker                       int count) override {
159*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < count; ++i) {
160*c8dee2aaSAndroid Build Coastguard Worker             dst[i] = QMul64(src[i], (uint8_t)i);
161*c8dee2aaSAndroid Build Coastguard Worker         }
162*c8dee2aaSAndroid Build Coastguard Worker     }
163*c8dee2aaSAndroid Build Coastguard Worker private:
164*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = MathBenchU32;
165*c8dee2aaSAndroid Build Coastguard Worker };
166*c8dee2aaSAndroid Build Coastguard Worker 
167*c8dee2aaSAndroid Build Coastguard Worker class QMul32Bench : public MathBenchU32 {
168*c8dee2aaSAndroid Build Coastguard Worker public:
QMul32Bench()169*c8dee2aaSAndroid Build Coastguard Worker     QMul32Bench() : INHERITED("qmul32") {}
170*c8dee2aaSAndroid Build Coastguard Worker protected:
performITest(uint32_t * SK_RESTRICT dst,const uint32_t * SK_RESTRICT src,int count)171*c8dee2aaSAndroid Build Coastguard Worker     void performITest(uint32_t* SK_RESTRICT dst,
172*c8dee2aaSAndroid Build Coastguard Worker                       const uint32_t* SK_RESTRICT src,
173*c8dee2aaSAndroid Build Coastguard Worker                       int count) override {
174*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < count; ++i) {
175*c8dee2aaSAndroid Build Coastguard Worker             dst[i] = SkAlphaMulQ(src[i], (uint8_t)i);
176*c8dee2aaSAndroid Build Coastguard Worker         }
177*c8dee2aaSAndroid Build Coastguard Worker     }
178*c8dee2aaSAndroid Build Coastguard Worker private:
179*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = MathBenchU32;
180*c8dee2aaSAndroid Build Coastguard Worker };
181*c8dee2aaSAndroid Build Coastguard Worker 
182*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
183*c8dee2aaSAndroid Build Coastguard Worker 
isFinite_int(float x)184*c8dee2aaSAndroid Build Coastguard Worker static bool isFinite_int(float x) {
185*c8dee2aaSAndroid Build Coastguard Worker     uint32_t bits = SkFloat2Bits(x);    // need unsigned for our shifts
186*c8dee2aaSAndroid Build Coastguard Worker     int exponent = bits << 1 >> 24;
187*c8dee2aaSAndroid Build Coastguard Worker     return exponent != 0xFF;
188*c8dee2aaSAndroid Build Coastguard Worker }
189*c8dee2aaSAndroid Build Coastguard Worker 
isFinite_mulzero(float x)190*c8dee2aaSAndroid Build Coastguard Worker static bool isFinite_mulzero(float x) {
191*c8dee2aaSAndroid Build Coastguard Worker     float y = x * 0;
192*c8dee2aaSAndroid Build Coastguard Worker     return y == y;
193*c8dee2aaSAndroid Build Coastguard Worker }
194*c8dee2aaSAndroid Build Coastguard Worker 
isfinite_and_int(const float data[4])195*c8dee2aaSAndroid Build Coastguard Worker static bool isfinite_and_int(const float data[4]) {
196*c8dee2aaSAndroid Build Coastguard Worker     return  isFinite_int(data[0]) && isFinite_int(data[1]) && isFinite_int(data[2]) && isFinite_int(data[3]);
197*c8dee2aaSAndroid Build Coastguard Worker }
198*c8dee2aaSAndroid Build Coastguard Worker 
isfinite_and_mulzero(const float data[4])199*c8dee2aaSAndroid Build Coastguard Worker static bool isfinite_and_mulzero(const float data[4]) {
200*c8dee2aaSAndroid Build Coastguard Worker     return  isFinite_mulzero(data[0]) && isFinite_mulzero(data[1]) && isFinite_mulzero(data[2]) && isFinite_mulzero(data[3]);
201*c8dee2aaSAndroid Build Coastguard Worker }
202*c8dee2aaSAndroid Build Coastguard Worker 
203*c8dee2aaSAndroid Build Coastguard Worker #define mulzeroadd(data)    (data[0]*0 + data[1]*0 + data[2]*0 + data[3]*0)
204*c8dee2aaSAndroid Build Coastguard Worker 
isfinite_plus_int(const float data[4])205*c8dee2aaSAndroid Build Coastguard Worker static bool isfinite_plus_int(const float data[4]) {
206*c8dee2aaSAndroid Build Coastguard Worker     return  isFinite_int(mulzeroadd(data));
207*c8dee2aaSAndroid Build Coastguard Worker }
208*c8dee2aaSAndroid Build Coastguard Worker 
isfinite_plus_mulzero(const float data[4])209*c8dee2aaSAndroid Build Coastguard Worker static bool isfinite_plus_mulzero(const float data[4]) {
210*c8dee2aaSAndroid Build Coastguard Worker     float x = mulzeroadd(data);
211*c8dee2aaSAndroid Build Coastguard Worker     return x == x;
212*c8dee2aaSAndroid Build Coastguard Worker }
213*c8dee2aaSAndroid Build Coastguard Worker 
214*c8dee2aaSAndroid Build Coastguard Worker typedef bool (*IsFiniteProc)(const float[]);
215*c8dee2aaSAndroid Build Coastguard Worker 
216*c8dee2aaSAndroid Build Coastguard Worker #define MAKEREC(name)   { name, #name }
217*c8dee2aaSAndroid Build Coastguard Worker 
218*c8dee2aaSAndroid Build Coastguard Worker static const struct {
219*c8dee2aaSAndroid Build Coastguard Worker     IsFiniteProc    fProc;
220*c8dee2aaSAndroid Build Coastguard Worker     const char*     fName;
221*c8dee2aaSAndroid Build Coastguard Worker } gRec[] = {
222*c8dee2aaSAndroid Build Coastguard Worker     MAKEREC(isfinite_and_int),
223*c8dee2aaSAndroid Build Coastguard Worker     MAKEREC(isfinite_and_mulzero),
224*c8dee2aaSAndroid Build Coastguard Worker     MAKEREC(isfinite_plus_int),
225*c8dee2aaSAndroid Build Coastguard Worker     MAKEREC(isfinite_plus_mulzero),
226*c8dee2aaSAndroid Build Coastguard Worker };
227*c8dee2aaSAndroid Build Coastguard Worker 
228*c8dee2aaSAndroid Build Coastguard Worker #undef MAKEREC
229*c8dee2aaSAndroid Build Coastguard Worker 
isFinite(const SkRect & r)230*c8dee2aaSAndroid Build Coastguard Worker static bool isFinite(const SkRect& r) {
231*c8dee2aaSAndroid Build Coastguard Worker     // x * 0 will be NaN iff x is infinity or NaN.
232*c8dee2aaSAndroid Build Coastguard Worker     // a + b will be NaN iff either a or b is NaN.
233*c8dee2aaSAndroid Build Coastguard Worker     float value = r.fLeft * 0 + r.fTop * 0 + r.fRight * 0 + r.fBottom * 0;
234*c8dee2aaSAndroid Build Coastguard Worker 
235*c8dee2aaSAndroid Build Coastguard Worker     // value is either NaN or it is finite (zero).
236*c8dee2aaSAndroid Build Coastguard Worker     // value==value will be true iff value is not NaN
237*c8dee2aaSAndroid Build Coastguard Worker     return value == value;
238*c8dee2aaSAndroid Build Coastguard Worker }
239*c8dee2aaSAndroid Build Coastguard Worker 
240*c8dee2aaSAndroid Build Coastguard Worker class IsFiniteBench : public Benchmark {
241*c8dee2aaSAndroid Build Coastguard Worker     enum {
242*c8dee2aaSAndroid Build Coastguard Worker         N = 1000,
243*c8dee2aaSAndroid Build Coastguard Worker     };
244*c8dee2aaSAndroid Build Coastguard Worker     float fData[N];
245*c8dee2aaSAndroid Build Coastguard Worker public:
246*c8dee2aaSAndroid Build Coastguard Worker 
IsFiniteBench(int index)247*c8dee2aaSAndroid Build Coastguard Worker     IsFiniteBench(int index)  {
248*c8dee2aaSAndroid Build Coastguard Worker         SkRandom rand;
249*c8dee2aaSAndroid Build Coastguard Worker 
250*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < N; ++i) {
251*c8dee2aaSAndroid Build Coastguard Worker             fData[i] = rand.nextSScalar1();
252*c8dee2aaSAndroid Build Coastguard Worker         }
253*c8dee2aaSAndroid Build Coastguard Worker 
254*c8dee2aaSAndroid Build Coastguard Worker         if (index < 0) {
255*c8dee2aaSAndroid Build Coastguard Worker             fProc = nullptr;
256*c8dee2aaSAndroid Build Coastguard Worker             fName = "isfinite_rect";
257*c8dee2aaSAndroid Build Coastguard Worker         } else {
258*c8dee2aaSAndroid Build Coastguard Worker             fProc = gRec[index].fProc;
259*c8dee2aaSAndroid Build Coastguard Worker             fName = gRec[index].fName;
260*c8dee2aaSAndroid Build Coastguard Worker         }
261*c8dee2aaSAndroid Build Coastguard Worker     }
262*c8dee2aaSAndroid Build Coastguard Worker 
isSuitableFor(Backend backend)263*c8dee2aaSAndroid Build Coastguard Worker     bool isSuitableFor(Backend backend) override {
264*c8dee2aaSAndroid Build Coastguard Worker         return backend == Backend::kNonRendering;
265*c8dee2aaSAndroid Build Coastguard Worker     }
266*c8dee2aaSAndroid Build Coastguard Worker 
267*c8dee2aaSAndroid Build Coastguard Worker protected:
onDraw(int loops,SkCanvas *)268*c8dee2aaSAndroid Build Coastguard Worker     void onDraw(int loops, SkCanvas*) override {
269*c8dee2aaSAndroid Build Coastguard Worker         IsFiniteProc proc = fProc;
270*c8dee2aaSAndroid Build Coastguard Worker         const float* data = fData;
271*c8dee2aaSAndroid Build Coastguard Worker         // do this so the compiler won't throw away the function call
272*c8dee2aaSAndroid Build Coastguard Worker         int counter = 0;
273*c8dee2aaSAndroid Build Coastguard Worker 
274*c8dee2aaSAndroid Build Coastguard Worker         if (proc) {
275*c8dee2aaSAndroid Build Coastguard Worker             for (int j = 0; j < loops; ++j) {
276*c8dee2aaSAndroid Build Coastguard Worker                 for (int i = 0; i < N - 4; ++i) {
277*c8dee2aaSAndroid Build Coastguard Worker                     counter += proc(&data[i]);
278*c8dee2aaSAndroid Build Coastguard Worker                 }
279*c8dee2aaSAndroid Build Coastguard Worker             }
280*c8dee2aaSAndroid Build Coastguard Worker         } else {
281*c8dee2aaSAndroid Build Coastguard Worker             for (int j = 0; j < loops; ++j) {
282*c8dee2aaSAndroid Build Coastguard Worker                 for (int i = 0; i < N - 4; ++i) {
283*c8dee2aaSAndroid Build Coastguard Worker                     const SkRect* r = reinterpret_cast<const SkRect*>(&data[i]);
284*c8dee2aaSAndroid Build Coastguard Worker                     if ((false)) { // avoid bit rot, suppress warning
285*c8dee2aaSAndroid Build Coastguard Worker                         isFinite(*r);
286*c8dee2aaSAndroid Build Coastguard Worker                     }
287*c8dee2aaSAndroid Build Coastguard Worker                     counter += r->isFinite();
288*c8dee2aaSAndroid Build Coastguard Worker                 }
289*c8dee2aaSAndroid Build Coastguard Worker             }
290*c8dee2aaSAndroid Build Coastguard Worker         }
291*c8dee2aaSAndroid Build Coastguard Worker 
292*c8dee2aaSAndroid Build Coastguard Worker         SkPaint paint;
293*c8dee2aaSAndroid Build Coastguard Worker         if (paint.getAlpha() == 0) {
294*c8dee2aaSAndroid Build Coastguard Worker             SkDebugf("%d\n", counter);
295*c8dee2aaSAndroid Build Coastguard Worker         }
296*c8dee2aaSAndroid Build Coastguard Worker     }
297*c8dee2aaSAndroid Build Coastguard Worker 
onGetName()298*c8dee2aaSAndroid Build Coastguard Worker     const char* onGetName() override {
299*c8dee2aaSAndroid Build Coastguard Worker         return fName;
300*c8dee2aaSAndroid Build Coastguard Worker     }
301*c8dee2aaSAndroid Build Coastguard Worker 
302*c8dee2aaSAndroid Build Coastguard Worker private:
303*c8dee2aaSAndroid Build Coastguard Worker     IsFiniteProc    fProc;
304*c8dee2aaSAndroid Build Coastguard Worker     const char*     fName;
305*c8dee2aaSAndroid Build Coastguard Worker 
306*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = Benchmark;
307*c8dee2aaSAndroid Build Coastguard Worker };
308*c8dee2aaSAndroid Build Coastguard Worker 
309*c8dee2aaSAndroid Build Coastguard Worker class FloorBench : public Benchmark {
310*c8dee2aaSAndroid Build Coastguard Worker     enum {
311*c8dee2aaSAndroid Build Coastguard Worker         ARRAY = 1000,
312*c8dee2aaSAndroid Build Coastguard Worker     };
313*c8dee2aaSAndroid Build Coastguard Worker     float fData[ARRAY];
314*c8dee2aaSAndroid Build Coastguard Worker     bool fFast;
315*c8dee2aaSAndroid Build Coastguard Worker public:
316*c8dee2aaSAndroid Build Coastguard Worker 
FloorBench(bool fast)317*c8dee2aaSAndroid Build Coastguard Worker     FloorBench(bool fast) : fFast(fast) {
318*c8dee2aaSAndroid Build Coastguard Worker         SkRandom rand;
319*c8dee2aaSAndroid Build Coastguard Worker 
320*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < ARRAY; ++i) {
321*c8dee2aaSAndroid Build Coastguard Worker             fData[i] = rand.nextSScalar1();
322*c8dee2aaSAndroid Build Coastguard Worker         }
323*c8dee2aaSAndroid Build Coastguard Worker 
324*c8dee2aaSAndroid Build Coastguard Worker         if (fast) {
325*c8dee2aaSAndroid Build Coastguard Worker             fName = "floor_fast";
326*c8dee2aaSAndroid Build Coastguard Worker         } else {
327*c8dee2aaSAndroid Build Coastguard Worker             fName = "floor_std";
328*c8dee2aaSAndroid Build Coastguard Worker         }
329*c8dee2aaSAndroid Build Coastguard Worker     }
330*c8dee2aaSAndroid Build Coastguard Worker 
isSuitableFor(Backend backend)331*c8dee2aaSAndroid Build Coastguard Worker     bool isSuitableFor(Backend backend) override {
332*c8dee2aaSAndroid Build Coastguard Worker         return backend == Backend::kNonRendering;
333*c8dee2aaSAndroid Build Coastguard Worker     }
334*c8dee2aaSAndroid Build Coastguard Worker 
process(float)335*c8dee2aaSAndroid Build Coastguard Worker     virtual void process(float) {}
336*c8dee2aaSAndroid Build Coastguard Worker 
337*c8dee2aaSAndroid Build Coastguard Worker protected:
onDraw(int loops,SkCanvas *)338*c8dee2aaSAndroid Build Coastguard Worker     void onDraw(int loops, SkCanvas*) override {
339*c8dee2aaSAndroid Build Coastguard Worker         SkRandom rand;
340*c8dee2aaSAndroid Build Coastguard Worker         float accum = 0;
341*c8dee2aaSAndroid Build Coastguard Worker         const float* data = fData;
342*c8dee2aaSAndroid Build Coastguard Worker 
343*c8dee2aaSAndroid Build Coastguard Worker         if (fFast) {
344*c8dee2aaSAndroid Build Coastguard Worker             for (int j = 0; j < loops; ++j) {
345*c8dee2aaSAndroid Build Coastguard Worker                 for (int i = 0; i < ARRAY; ++i) {
346*c8dee2aaSAndroid Build Coastguard Worker                     accum += fast_floor(data[i]);
347*c8dee2aaSAndroid Build Coastguard Worker                 }
348*c8dee2aaSAndroid Build Coastguard Worker                 this->process(accum);
349*c8dee2aaSAndroid Build Coastguard Worker             }
350*c8dee2aaSAndroid Build Coastguard Worker         } else {
351*c8dee2aaSAndroid Build Coastguard Worker             for (int j = 0; j < loops; ++j) {
352*c8dee2aaSAndroid Build Coastguard Worker                 for (int i = 0; i < ARRAY; ++i) {
353*c8dee2aaSAndroid Build Coastguard Worker                     accum += std::floor(data[i]);
354*c8dee2aaSAndroid Build Coastguard Worker                 }
355*c8dee2aaSAndroid Build Coastguard Worker                 this->process(accum);
356*c8dee2aaSAndroid Build Coastguard Worker             }
357*c8dee2aaSAndroid Build Coastguard Worker         }
358*c8dee2aaSAndroid Build Coastguard Worker     }
359*c8dee2aaSAndroid Build Coastguard Worker 
onGetName()360*c8dee2aaSAndroid Build Coastguard Worker     const char* onGetName() override {
361*c8dee2aaSAndroid Build Coastguard Worker         return fName;
362*c8dee2aaSAndroid Build Coastguard Worker     }
363*c8dee2aaSAndroid Build Coastguard Worker 
364*c8dee2aaSAndroid Build Coastguard Worker private:
365*c8dee2aaSAndroid Build Coastguard Worker     const char*     fName;
366*c8dee2aaSAndroid Build Coastguard Worker 
367*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = Benchmark;
368*c8dee2aaSAndroid Build Coastguard Worker };
369*c8dee2aaSAndroid Build Coastguard Worker 
370*c8dee2aaSAndroid Build Coastguard Worker class CLZBench : public Benchmark {
371*c8dee2aaSAndroid Build Coastguard Worker     enum {
372*c8dee2aaSAndroid Build Coastguard Worker         ARRAY = 1000,
373*c8dee2aaSAndroid Build Coastguard Worker     };
374*c8dee2aaSAndroid Build Coastguard Worker     uint32_t fData[ARRAY];
375*c8dee2aaSAndroid Build Coastguard Worker     bool fUsePortable;
376*c8dee2aaSAndroid Build Coastguard Worker 
377*c8dee2aaSAndroid Build Coastguard Worker public:
CLZBench(bool usePortable)378*c8dee2aaSAndroid Build Coastguard Worker     CLZBench(bool usePortable) : fUsePortable(usePortable) {
379*c8dee2aaSAndroid Build Coastguard Worker 
380*c8dee2aaSAndroid Build Coastguard Worker         SkRandom rand;
381*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < ARRAY; ++i) {
382*c8dee2aaSAndroid Build Coastguard Worker             fData[i] = rand.nextU();
383*c8dee2aaSAndroid Build Coastguard Worker         }
384*c8dee2aaSAndroid Build Coastguard Worker 
385*c8dee2aaSAndroid Build Coastguard Worker         if (fUsePortable) {
386*c8dee2aaSAndroid Build Coastguard Worker             fName = "clz_portable";
387*c8dee2aaSAndroid Build Coastguard Worker         } else {
388*c8dee2aaSAndroid Build Coastguard Worker             fName = "clz_intrinsic";
389*c8dee2aaSAndroid Build Coastguard Worker         }
390*c8dee2aaSAndroid Build Coastguard Worker     }
391*c8dee2aaSAndroid Build Coastguard Worker 
isSuitableFor(Backend backend)392*c8dee2aaSAndroid Build Coastguard Worker     bool isSuitableFor(Backend backend) override {
393*c8dee2aaSAndroid Build Coastguard Worker         return backend == Backend::kNonRendering;
394*c8dee2aaSAndroid Build Coastguard Worker     }
395*c8dee2aaSAndroid Build Coastguard Worker 
396*c8dee2aaSAndroid Build Coastguard Worker     // just so the compiler doesn't remove our loops
process(int)397*c8dee2aaSAndroid Build Coastguard Worker     virtual void process(int) {}
398*c8dee2aaSAndroid Build Coastguard Worker 
399*c8dee2aaSAndroid Build Coastguard Worker protected:
onDraw(int loops,SkCanvas *)400*c8dee2aaSAndroid Build Coastguard Worker     void onDraw(int loops, SkCanvas*) override {
401*c8dee2aaSAndroid Build Coastguard Worker         int accum = 0;
402*c8dee2aaSAndroid Build Coastguard Worker 
403*c8dee2aaSAndroid Build Coastguard Worker         if (fUsePortable) {
404*c8dee2aaSAndroid Build Coastguard Worker             for (int j = 0; j < loops; ++j) {
405*c8dee2aaSAndroid Build Coastguard Worker                 for (int i = 0; i < ARRAY; ++i) {
406*c8dee2aaSAndroid Build Coastguard Worker                     accum += SkCLZ_portable(fData[i]);
407*c8dee2aaSAndroid Build Coastguard Worker                 }
408*c8dee2aaSAndroid Build Coastguard Worker                 this->process(accum);
409*c8dee2aaSAndroid Build Coastguard Worker             }
410*c8dee2aaSAndroid Build Coastguard Worker         } else {
411*c8dee2aaSAndroid Build Coastguard Worker             for (int j = 0; j < loops; ++j) {
412*c8dee2aaSAndroid Build Coastguard Worker                 for (int i = 0; i < ARRAY; ++i) {
413*c8dee2aaSAndroid Build Coastguard Worker                     accum += SkCLZ(fData[i]);
414*c8dee2aaSAndroid Build Coastguard Worker                 }
415*c8dee2aaSAndroid Build Coastguard Worker                 this->process(accum);
416*c8dee2aaSAndroid Build Coastguard Worker             }
417*c8dee2aaSAndroid Build Coastguard Worker         }
418*c8dee2aaSAndroid Build Coastguard Worker     }
419*c8dee2aaSAndroid Build Coastguard Worker 
onGetName()420*c8dee2aaSAndroid Build Coastguard Worker     const char* onGetName() override {
421*c8dee2aaSAndroid Build Coastguard Worker         return fName;
422*c8dee2aaSAndroid Build Coastguard Worker     }
423*c8dee2aaSAndroid Build Coastguard Worker 
424*c8dee2aaSAndroid Build Coastguard Worker private:
425*c8dee2aaSAndroid Build Coastguard Worker     const char* fName;
426*c8dee2aaSAndroid Build Coastguard Worker 
427*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = Benchmark;
428*c8dee2aaSAndroid Build Coastguard Worker };
429*c8dee2aaSAndroid Build Coastguard Worker 
430*c8dee2aaSAndroid Build Coastguard Worker class CTZBench : public Benchmark {
431*c8dee2aaSAndroid Build Coastguard Worker     enum {
432*c8dee2aaSAndroid Build Coastguard Worker         ARRAY = 1000,
433*c8dee2aaSAndroid Build Coastguard Worker     };
434*c8dee2aaSAndroid Build Coastguard Worker     uint32_t fData[ARRAY];
435*c8dee2aaSAndroid Build Coastguard Worker     bool fUsePortable;
436*c8dee2aaSAndroid Build Coastguard Worker 
437*c8dee2aaSAndroid Build Coastguard Worker public:
CTZBench(bool usePortable)438*c8dee2aaSAndroid Build Coastguard Worker     CTZBench(bool usePortable) : fUsePortable(usePortable) {
439*c8dee2aaSAndroid Build Coastguard Worker 
440*c8dee2aaSAndroid Build Coastguard Worker         SkRandom rand;
441*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < ARRAY; ++i) {
442*c8dee2aaSAndroid Build Coastguard Worker             fData[i] = rand.nextU();
443*c8dee2aaSAndroid Build Coastguard Worker         }
444*c8dee2aaSAndroid Build Coastguard Worker 
445*c8dee2aaSAndroid Build Coastguard Worker         if (fUsePortable) {
446*c8dee2aaSAndroid Build Coastguard Worker             fName = "ctz_portable";
447*c8dee2aaSAndroid Build Coastguard Worker         } else {
448*c8dee2aaSAndroid Build Coastguard Worker             fName = "ctz_intrinsic";
449*c8dee2aaSAndroid Build Coastguard Worker         }
450*c8dee2aaSAndroid Build Coastguard Worker     }
451*c8dee2aaSAndroid Build Coastguard Worker 
isSuitableFor(Backend backend)452*c8dee2aaSAndroid Build Coastguard Worker     bool isSuitableFor(Backend backend) override {
453*c8dee2aaSAndroid Build Coastguard Worker         return backend == Backend::kNonRendering;
454*c8dee2aaSAndroid Build Coastguard Worker     }
455*c8dee2aaSAndroid Build Coastguard Worker 
456*c8dee2aaSAndroid Build Coastguard Worker     // just so the compiler doesn't remove our loops
process(int)457*c8dee2aaSAndroid Build Coastguard Worker     virtual void process(int) {}
458*c8dee2aaSAndroid Build Coastguard Worker 
459*c8dee2aaSAndroid Build Coastguard Worker protected:
onDraw(int loops,SkCanvas *)460*c8dee2aaSAndroid Build Coastguard Worker     void onDraw(int loops, SkCanvas*) override {
461*c8dee2aaSAndroid Build Coastguard Worker         int accum = 0;
462*c8dee2aaSAndroid Build Coastguard Worker 
463*c8dee2aaSAndroid Build Coastguard Worker         if (fUsePortable) {
464*c8dee2aaSAndroid Build Coastguard Worker             for (int j = 0; j < loops; ++j) {
465*c8dee2aaSAndroid Build Coastguard Worker                 for (int i = 0; i < ARRAY; ++i) {
466*c8dee2aaSAndroid Build Coastguard Worker                     accum += SkCTZ_portable(fData[i]);
467*c8dee2aaSAndroid Build Coastguard Worker                 }
468*c8dee2aaSAndroid Build Coastguard Worker                 this->process(accum);
469*c8dee2aaSAndroid Build Coastguard Worker             }
470*c8dee2aaSAndroid Build Coastguard Worker         } else {
471*c8dee2aaSAndroid Build Coastguard Worker             for (int j = 0; j < loops; ++j) {
472*c8dee2aaSAndroid Build Coastguard Worker                 for (int i = 0; i < ARRAY; ++i) {
473*c8dee2aaSAndroid Build Coastguard Worker                     accum += SkCTZ(fData[i]);
474*c8dee2aaSAndroid Build Coastguard Worker                 }
475*c8dee2aaSAndroid Build Coastguard Worker                 this->process(accum);
476*c8dee2aaSAndroid Build Coastguard Worker             }
477*c8dee2aaSAndroid Build Coastguard Worker         }
478*c8dee2aaSAndroid Build Coastguard Worker     }
479*c8dee2aaSAndroid Build Coastguard Worker 
onGetName()480*c8dee2aaSAndroid Build Coastguard Worker     const char* onGetName() override {
481*c8dee2aaSAndroid Build Coastguard Worker         return fName;
482*c8dee2aaSAndroid Build Coastguard Worker     }
483*c8dee2aaSAndroid Build Coastguard Worker 
484*c8dee2aaSAndroid Build Coastguard Worker private:
485*c8dee2aaSAndroid Build Coastguard Worker     const char* fName;
486*c8dee2aaSAndroid Build Coastguard Worker 
487*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = Benchmark;
488*c8dee2aaSAndroid Build Coastguard Worker };
489*c8dee2aaSAndroid Build Coastguard Worker 
490*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
491*c8dee2aaSAndroid Build Coastguard Worker 
492*c8dee2aaSAndroid Build Coastguard Worker class NormalizeBench : public Benchmark {
493*c8dee2aaSAndroid Build Coastguard Worker     enum {
494*c8dee2aaSAndroid Build Coastguard Worker         ARRAY =1000,
495*c8dee2aaSAndroid Build Coastguard Worker     };
496*c8dee2aaSAndroid Build Coastguard Worker     SkVector fVec[ARRAY];
497*c8dee2aaSAndroid Build Coastguard Worker 
498*c8dee2aaSAndroid Build Coastguard Worker public:
NormalizeBench()499*c8dee2aaSAndroid Build Coastguard Worker     NormalizeBench() {
500*c8dee2aaSAndroid Build Coastguard Worker         SkRandom rand;
501*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < ARRAY; ++i) {
502*c8dee2aaSAndroid Build Coastguard Worker             fVec[i].set(rand.nextSScalar1(), rand.nextSScalar1());
503*c8dee2aaSAndroid Build Coastguard Worker         }
504*c8dee2aaSAndroid Build Coastguard Worker 
505*c8dee2aaSAndroid Build Coastguard Worker         fName = "point_normalize";
506*c8dee2aaSAndroid Build Coastguard Worker     }
507*c8dee2aaSAndroid Build Coastguard Worker 
isSuitableFor(Backend backend)508*c8dee2aaSAndroid Build Coastguard Worker     bool isSuitableFor(Backend backend) override {
509*c8dee2aaSAndroid Build Coastguard Worker         return backend == Backend::kNonRendering;
510*c8dee2aaSAndroid Build Coastguard Worker     }
511*c8dee2aaSAndroid Build Coastguard Worker 
512*c8dee2aaSAndroid Build Coastguard Worker     // just so the compiler doesn't remove our loops
process(int)513*c8dee2aaSAndroid Build Coastguard Worker     virtual void process(int) {}
514*c8dee2aaSAndroid Build Coastguard Worker 
515*c8dee2aaSAndroid Build Coastguard Worker protected:
onDraw(int loops,SkCanvas *)516*c8dee2aaSAndroid Build Coastguard Worker     void onDraw(int loops, SkCanvas*) override {
517*c8dee2aaSAndroid Build Coastguard Worker         int accum = 0;
518*c8dee2aaSAndroid Build Coastguard Worker 
519*c8dee2aaSAndroid Build Coastguard Worker         for (int j = 0; j < loops; ++j) {
520*c8dee2aaSAndroid Build Coastguard Worker             for (int i = 0; i < ARRAY; ++i) {
521*c8dee2aaSAndroid Build Coastguard Worker                 accum += fVec[i].normalize();
522*c8dee2aaSAndroid Build Coastguard Worker             }
523*c8dee2aaSAndroid Build Coastguard Worker             this->process(accum);
524*c8dee2aaSAndroid Build Coastguard Worker         }
525*c8dee2aaSAndroid Build Coastguard Worker     }
526*c8dee2aaSAndroid Build Coastguard Worker 
onGetName()527*c8dee2aaSAndroid Build Coastguard Worker     const char* onGetName() override {
528*c8dee2aaSAndroid Build Coastguard Worker         return fName;
529*c8dee2aaSAndroid Build Coastguard Worker     }
530*c8dee2aaSAndroid Build Coastguard Worker 
531*c8dee2aaSAndroid Build Coastguard Worker private:
532*c8dee2aaSAndroid Build Coastguard Worker     const char* fName;
533*c8dee2aaSAndroid Build Coastguard Worker 
534*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = Benchmark;
535*c8dee2aaSAndroid Build Coastguard Worker };
536*c8dee2aaSAndroid Build Coastguard Worker 
537*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
538*c8dee2aaSAndroid Build Coastguard Worker 
539*c8dee2aaSAndroid Build Coastguard Worker class FixedMathBench : public Benchmark {
540*c8dee2aaSAndroid Build Coastguard Worker     enum {
541*c8dee2aaSAndroid Build Coastguard Worker         N = 1000,
542*c8dee2aaSAndroid Build Coastguard Worker     };
543*c8dee2aaSAndroid Build Coastguard Worker     float fData[N];
544*c8dee2aaSAndroid Build Coastguard Worker     SkFixed fResult[N];
545*c8dee2aaSAndroid Build Coastguard Worker public:
546*c8dee2aaSAndroid Build Coastguard Worker 
FixedMathBench()547*c8dee2aaSAndroid Build Coastguard Worker     FixedMathBench()  {
548*c8dee2aaSAndroid Build Coastguard Worker         SkRandom rand;
549*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < N; ++i) {
550*c8dee2aaSAndroid Build Coastguard Worker             fData[i] = rand.nextSScalar1();
551*c8dee2aaSAndroid Build Coastguard Worker         }
552*c8dee2aaSAndroid Build Coastguard Worker 
553*c8dee2aaSAndroid Build Coastguard Worker     }
554*c8dee2aaSAndroid Build Coastguard Worker 
isSuitableFor(Backend backend)555*c8dee2aaSAndroid Build Coastguard Worker     bool isSuitableFor(Backend backend) override {
556*c8dee2aaSAndroid Build Coastguard Worker         return backend == Backend::kNonRendering;
557*c8dee2aaSAndroid Build Coastguard Worker     }
558*c8dee2aaSAndroid Build Coastguard Worker 
559*c8dee2aaSAndroid Build Coastguard Worker protected:
onDraw(int loops,SkCanvas *)560*c8dee2aaSAndroid Build Coastguard Worker     void onDraw(int loops, SkCanvas*) override {
561*c8dee2aaSAndroid Build Coastguard Worker         for (int j = 0; j < loops; ++j) {
562*c8dee2aaSAndroid Build Coastguard Worker             for (int i = 0; i < N - 4; ++i) {
563*c8dee2aaSAndroid Build Coastguard Worker                 fResult[i] = SkFloatToFixed(fData[i]);
564*c8dee2aaSAndroid Build Coastguard Worker             }
565*c8dee2aaSAndroid Build Coastguard Worker         }
566*c8dee2aaSAndroid Build Coastguard Worker 
567*c8dee2aaSAndroid Build Coastguard Worker         SkPaint paint;
568*c8dee2aaSAndroid Build Coastguard Worker         if (paint.getAlpha() == 0) {
569*c8dee2aaSAndroid Build Coastguard Worker             SkDebugf("%d\n", fResult[0]);
570*c8dee2aaSAndroid Build Coastguard Worker         }
571*c8dee2aaSAndroid Build Coastguard Worker     }
572*c8dee2aaSAndroid Build Coastguard Worker 
onGetName()573*c8dee2aaSAndroid Build Coastguard Worker     const char* onGetName() override {
574*c8dee2aaSAndroid Build Coastguard Worker         return "float_to_fixed";
575*c8dee2aaSAndroid Build Coastguard Worker     }
576*c8dee2aaSAndroid Build Coastguard Worker 
577*c8dee2aaSAndroid Build Coastguard Worker private:
578*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = Benchmark;
579*c8dee2aaSAndroid Build Coastguard Worker };
580*c8dee2aaSAndroid Build Coastguard Worker 
581*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
582*c8dee2aaSAndroid Build Coastguard Worker 
583*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new NoOpMathBench(); )
584*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new SkRSqrtMathBench(); )
585*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new SlowISqrtMathBench(); )
586*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new FastISqrtMathBench(); )
587*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new QMul64Bench(); )
588*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new QMul32Bench(); )
589*c8dee2aaSAndroid Build Coastguard Worker 
590*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new IsFiniteBench(-1); )
591*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new IsFiniteBench(0); )
592*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new IsFiniteBench(1); )
593*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new IsFiniteBench(2); )
594*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new IsFiniteBench(3); )
595*c8dee2aaSAndroid Build Coastguard Worker 
596*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new FloorBench(false); )
597*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new FloorBench(true); )
598*c8dee2aaSAndroid Build Coastguard Worker 
599*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CLZBench(false); )
600*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CLZBench(true); )
601*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CTZBench(false); )
602*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CTZBench(true); )
603*c8dee2aaSAndroid Build Coastguard Worker 
604*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new NormalizeBench(); )
605*c8dee2aaSAndroid Build Coastguard Worker 
606*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new FixedMathBench(); )
607*c8dee2aaSAndroid Build Coastguard Worker 
608*c8dee2aaSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////
609*c8dee2aaSAndroid Build Coastguard Worker 
610*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkFloatBits.h"
611*c8dee2aaSAndroid Build Coastguard Worker class Floor2IntBench : public Benchmark {
612*c8dee2aaSAndroid Build Coastguard Worker     enum {
613*c8dee2aaSAndroid Build Coastguard Worker         ARRAY = 1000,
614*c8dee2aaSAndroid Build Coastguard Worker     };
615*c8dee2aaSAndroid Build Coastguard Worker     float fData[ARRAY];
616*c8dee2aaSAndroid Build Coastguard Worker     const bool fSat;
617*c8dee2aaSAndroid Build Coastguard Worker public:
618*c8dee2aaSAndroid Build Coastguard Worker 
Floor2IntBench(bool sat)619*c8dee2aaSAndroid Build Coastguard Worker     Floor2IntBench(bool sat) : fSat(sat) {
620*c8dee2aaSAndroid Build Coastguard Worker         SkRandom rand;
621*c8dee2aaSAndroid Build Coastguard Worker 
622*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < ARRAY; ++i) {
623*c8dee2aaSAndroid Build Coastguard Worker             fData[i] = SkBits2Float(rand.nextU());
624*c8dee2aaSAndroid Build Coastguard Worker         }
625*c8dee2aaSAndroid Build Coastguard Worker 
626*c8dee2aaSAndroid Build Coastguard Worker         if (sat) {
627*c8dee2aaSAndroid Build Coastguard Worker             fName = "floor2int_sat";
628*c8dee2aaSAndroid Build Coastguard Worker         } else {
629*c8dee2aaSAndroid Build Coastguard Worker             fName = "floor2int_undef";
630*c8dee2aaSAndroid Build Coastguard Worker         }
631*c8dee2aaSAndroid Build Coastguard Worker     }
632*c8dee2aaSAndroid Build Coastguard Worker 
isSuitableFor(Backend backend)633*c8dee2aaSAndroid Build Coastguard Worker     bool isSuitableFor(Backend backend) override {
634*c8dee2aaSAndroid Build Coastguard Worker         return backend == Backend::kNonRendering;
635*c8dee2aaSAndroid Build Coastguard Worker     }
636*c8dee2aaSAndroid Build Coastguard Worker 
637*c8dee2aaSAndroid Build Coastguard Worker     // These exist to try to stop the compiler from detecting what we doing, and throwing
638*c8dee2aaSAndroid Build Coastguard Worker     // parts away (or knowing exactly how big the loop counts are).
process(unsigned)639*c8dee2aaSAndroid Build Coastguard Worker     virtual void process(unsigned) {}
count()640*c8dee2aaSAndroid Build Coastguard Worker     virtual int count() { return ARRAY; }
641*c8dee2aaSAndroid Build Coastguard Worker 
642*c8dee2aaSAndroid Build Coastguard Worker protected:
onDraw(int loops,SkCanvas *)643*c8dee2aaSAndroid Build Coastguard Worker     void onDraw(int loops, SkCanvas*) override {
644*c8dee2aaSAndroid Build Coastguard Worker         // used unsigned to avoid undefined behavior if/when the += might overflow
645*c8dee2aaSAndroid Build Coastguard Worker         unsigned accum = 0;
646*c8dee2aaSAndroid Build Coastguard Worker 
647*c8dee2aaSAndroid Build Coastguard Worker         for (int j = 0; j < loops; ++j) {
648*c8dee2aaSAndroid Build Coastguard Worker             int n = this->count();
649*c8dee2aaSAndroid Build Coastguard Worker             if (fSat) {
650*c8dee2aaSAndroid Build Coastguard Worker                 for (int i = 0; i < n; ++i) {
651*c8dee2aaSAndroid Build Coastguard Worker                     accum += sk_float_floor2int(fData[i]);
652*c8dee2aaSAndroid Build Coastguard Worker                 }
653*c8dee2aaSAndroid Build Coastguard Worker             } else {
654*c8dee2aaSAndroid Build Coastguard Worker                 for (int i = 0; i < n; ++i) {
655*c8dee2aaSAndroid Build Coastguard Worker                     accum += sk_float_floor2int_no_saturate(fData[i]);
656*c8dee2aaSAndroid Build Coastguard Worker                 }
657*c8dee2aaSAndroid Build Coastguard Worker             }
658*c8dee2aaSAndroid Build Coastguard Worker             this->process(accum);
659*c8dee2aaSAndroid Build Coastguard Worker         }
660*c8dee2aaSAndroid Build Coastguard Worker     }
661*c8dee2aaSAndroid Build Coastguard Worker 
onGetName()662*c8dee2aaSAndroid Build Coastguard Worker     const char* onGetName() override { return fName; }
663*c8dee2aaSAndroid Build Coastguard Worker 
664*c8dee2aaSAndroid Build Coastguard Worker private:
665*c8dee2aaSAndroid Build Coastguard Worker     const char* fName;
666*c8dee2aaSAndroid Build Coastguard Worker 
667*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = Benchmark;
668*c8dee2aaSAndroid Build Coastguard Worker };
669*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new Floor2IntBench(false); )
670*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new Floor2IntBench(true); )
671*c8dee2aaSAndroid Build Coastguard Worker 
672