11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkBenchmark.h"
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkColorPriv.h"
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkMatrix.h"
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkRandom.h"
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkString.h"
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkPaint.h"
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass MathBench : public SkBenchmark {
91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    enum {
101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        kBuffer = 100,
111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        kLoop   = 10000
121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkString    fName;
141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    float       fSrc[kBuffer], fDst[kBuffer];
151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic:
161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    MathBench(void* param, const char name[]) : INHERITED(param) {
171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fName.printf("math_%s", name);
181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkRandom rand;
201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int i = 0; i < kBuffer; ++i) {
211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fSrc[i] = rand.nextSScalar1();
221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void performTest(float dst[], const float src[], int count) = 0;
261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprotected:
281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual int mulLoopCount() const { return 1; }
291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual const char* onGetName() {
311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return fName.c_str();
321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void onDraw(SkCanvas* canvas) {
351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int n = SkBENCHLOOP(kLoop * this->mulLoopCount());
361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int i = 0; i < n; i++) {
371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            this->performTest(fDst, fSrc, kBuffer);
381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprivate:
421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    typedef SkBenchmark INHERITED;
431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass MathBenchU32 : public MathBench {
461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic:
471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    MathBenchU32(void* param, const char name[]) : INHERITED(param, name) {}
481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprotected:
501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void performITest(uint32_t* dst, const uint32_t* src, int count) = 0;
511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void performTest(float* SK_RESTRICT dst, const float* SK_RESTRICT src,
531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             int count) SK_OVERRIDE {
541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        uint32_t* d = SkTCast<uint32_t*>(dst);
551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const uint32_t* s = SkTCast<const uint32_t*>(src);
561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        this->performITest(d, s, count);
571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprivate:
591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    typedef MathBench INHERITED;
601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass NoOpMathBench : public MathBench {
651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic:
661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    NoOpMathBench(void* param) : INHERITED(param, "noOp") {}
671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprotected:
681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void performTest(float dst[], const float src[], int count) {
691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int i = 0; i < count; ++i) {
701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            dst[i] = src[i] + 1;
711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprivate:
741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    typedef MathBench INHERITED;
751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass SlowISqrtMathBench : public MathBench {
781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic:
791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SlowISqrtMathBench(void* param) : INHERITED(param, "slowIsqrt") {}
801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprotected:
811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void performTest(float dst[], const float src[], int count) {
821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int i = 0; i < count; ++i) {
831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            dst[i] = 1.0f / sk_float_sqrt(src[i]);
841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprivate:
871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    typedef MathBench INHERITED;
881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic inline float SkFastInvSqrt(float x) {
911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    float xhalf = 0.5f*x;
921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int i = *(int*)&x;
931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    i = 0x5f3759df - (i>>1);
941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    x = *(float*)&i;
951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    x = x*(1.5f-xhalf*x*x);
961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//    x = x*(1.5f-xhalf*x*x); // this line takes err from 10^-3 to 10^-6
971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return x;
981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass FastISqrtMathBench : public MathBench {
1011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic:
1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    FastISqrtMathBench(void* param) : INHERITED(param, "fastIsqrt") {}
1031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprotected:
1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void performTest(float dst[], const float src[], int count) {
1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int i = 0; i < count; ++i) {
1061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            dst[i] = SkFastInvSqrt(src[i]);
1071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprivate:
1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    typedef MathBench INHERITED;
1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic inline uint32_t QMul64(uint32_t value, U8CPU alpha) {
1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkASSERT((uint8_t)alpha == alpha);
1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const uint32_t mask = 0xFF00FF;
1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    uint64_t tmp = value;
1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    tmp = (tmp & mask) | ((tmp & ~mask) << 24);
1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    tmp *= alpha;
1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return ((tmp >> 8) & mask) | ((tmp >> 32) & ~mask);
1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass QMul64Bench : public MathBenchU32 {
1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic:
1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    QMul64Bench(void* param) : INHERITED(param, "qmul64") {}
1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprotected:
1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void performITest(uint32_t* SK_RESTRICT dst,
1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                              const uint32_t* SK_RESTRICT src,
1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                              int count) SK_OVERRIDE {
1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int i = 0; i < count; ++i) {
1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            dst[i] = QMul64(src[i], (uint8_t)i);
1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprivate:
1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    typedef MathBenchU32 INHERITED;
1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass QMul32Bench : public MathBenchU32 {
1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic:
1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    QMul32Bench(void* param) : INHERITED(param, "qmul32") {}
1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprotected:
1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void performITest(uint32_t* SK_RESTRICT dst,
1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                              const uint32_t* SK_RESTRICT src,
1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                              int count) SK_OVERRIDE {
1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int i = 0; i < count; ++i) {
1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            dst[i] = SkAlphaMulQ(src[i], (uint8_t)i);
1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprivate:
1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    typedef MathBenchU32 INHERITED;
1511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
1521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
1541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool isFinite_int(float x) {
1561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    uint32_t bits = SkFloat2Bits(x);    // need unsigned for our shifts
1571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int exponent = bits << 1 >> 24;
1581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return exponent != 0xFF;
1591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool isFinite_float(float x) {
1621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return sk_float_isfinite(x);
1631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool isFinite_mulzero(float x) {
1661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    float y = x * 0;
1671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return y == y;
1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool isfinite_and_int(const float data[4]) {
1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return  isFinite_int(data[0]) && isFinite_int(data[1]) && isFinite_int(data[2]) && isFinite_int(data[3]);
1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool isfinite_and_float(const float data[4]) {
1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return  isFinite_float(data[0]) && isFinite_float(data[1]) && isFinite_float(data[2]) && isFinite_float(data[3]);
1761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool isfinite_and_mulzero(const float data[4]) {
1791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return  isFinite_mulzero(data[0]) && isFinite_mulzero(data[1]) && isFinite_mulzero(data[2]) && isFinite_mulzero(data[3]);
1801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define mulzeroadd(data)    (data[0]*0 + data[1]*0 + data[2]*0 + data[3]*0)
1831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool isfinite_plus_int(const float data[4]) {
1851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return  isFinite_int(mulzeroadd(data));
1861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool isfinite_plus_float(const float data[4]) {
1891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return  !sk_float_isnan(mulzeroadd(data));
1901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool isfinite_plus_mulzero(const float data[4]) {
1931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    float x = mulzeroadd(data);
1941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return x == x;
1951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergertypedef bool (*IsFiniteProc)(const float[]);
1981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define MAKEREC(name)   { name, #name }
2001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const struct {
2021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    IsFiniteProc    fProc;
2031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const char*     fName;
2041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} gRec[] = {
2051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    MAKEREC(isfinite_and_int),
2061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    MAKEREC(isfinite_and_float),
2071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    MAKEREC(isfinite_and_mulzero),
2081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    MAKEREC(isfinite_plus_int),
2091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    MAKEREC(isfinite_plus_float),
2101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    MAKEREC(isfinite_plus_mulzero),
2111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
2121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#undef MAKEREC
2141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool isFinite(const SkRect& r) {
2161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // x * 0 will be NaN iff x is infinity or NaN.
2171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // a + b will be NaN iff either a or b is NaN.
2181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    float value = r.fLeft * 0 + r.fTop * 0 + r.fRight * 0 + r.fBottom * 0;
2191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // value is either NaN or it is finite (zero).
2211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // value==value will be true iff value is not NaN
2221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return value == value;
2231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass IsFiniteBench : public SkBenchmark {
2261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    enum {
2271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        N = SkBENCHLOOP(1000),
2281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        NN = SkBENCHLOOP(1000),
2291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
2301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    float fData[N];
2311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic:
2321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    IsFiniteBench(void* param, int index) : INHERITED(param) {
2341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkRandom rand;
2351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int i = 0; i < N; ++i) {
2371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fData[i] = rand.nextSScalar1();
2381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
2391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (index < 0) {
2411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fProc = NULL;
2421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fName = "isfinite_rect";
2431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
2441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fProc = gRec[index].fProc;
2451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fName = gRec[index].fName;
2461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
2471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
2481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprotected:
2501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void onDraw(SkCanvas* canvas) {
2511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        IsFiniteProc proc = fProc;
2521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const float* data = fData;
2531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // do this so the compiler won't throw away the function call
2541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int counter = 0;
2551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (proc) {
2571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            for (int j = 0; j < NN; ++j) {
2581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                for (int i = 0; i < N - 4; ++i) {
2591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    counter += proc(&data[i]);
2601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                }
2611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
2621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
2631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            for (int j = 0; j < NN; ++j) {
2641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                for (int i = 0; i < N - 4; ++i) {
2651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    const SkRect* r = reinterpret_cast<const SkRect*>(&data[i]);
2661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    counter += r->isFinite();
2671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                }
2681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
2691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
2701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPaint paint;
2721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (paint.getAlpha() == 0) {
2731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkDebugf("%d\n", counter);
2741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
2751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
2761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual const char* onGetName() {
2781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return fName;
2791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
2801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprivate:
2821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    IsFiniteProc    fProc;
2831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const char*     fName;
2841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    typedef SkBenchmark INHERITED;
2861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
2871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
2891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkBenchmark* M0(void* p) { return new NoOpMathBench(p); }
2911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkBenchmark* M1(void* p) { return new SlowISqrtMathBench(p); }
2921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkBenchmark* M2(void* p) { return new FastISqrtMathBench(p); }
2931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkBenchmark* M3(void* p) { return new QMul64Bench(p); }
2941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkBenchmark* M4(void* p) { return new QMul32Bench(p); }
2951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkBenchmark* M5neg1(void* p) { return new IsFiniteBench(p, -1); }
2971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkBenchmark* M50(void* p) { return new IsFiniteBench(p, 0); }
2981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkBenchmark* M51(void* p) { return new IsFiniteBench(p, 1); }
2991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkBenchmark* M52(void* p) { return new IsFiniteBench(p, 2); }
3001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkBenchmark* M53(void* p) { return new IsFiniteBench(p, 3); }
3011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkBenchmark* M54(void* p) { return new IsFiniteBench(p, 4); }
3021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkBenchmark* M55(void* p) { return new IsFiniteBench(p, 5); }
3031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic BenchRegistry gReg0(M0);
3051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic BenchRegistry gReg1(M1);
3061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic BenchRegistry gReg2(M2);
3071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic BenchRegistry gReg3(M3);
3081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic BenchRegistry gReg4(M4);
3091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic BenchRegistry gReg5neg1(M5neg1);
3111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic BenchRegistry gReg50(M50);
3121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic BenchRegistry gReg51(M51);
3131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic BenchRegistry gReg52(M52);
3141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic BenchRegistry gReg53(M53);
3151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic BenchRegistry gReg54(M54);
3161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic BenchRegistry gReg55(M55);
317