180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "Test.h"
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFloatBits.h"
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFloatingPoint.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkMathPriv.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPoint.h"
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkRandom.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColorPriv.h"
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic void test_clz(skiatest::Reporter* reporter) {
177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    REPORTER_ASSERT(reporter, 32 == SkCLZ(0));
187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    REPORTER_ASSERT(reporter, 31 == SkCLZ(1));
197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    REPORTER_ASSERT(reporter, 1 == SkCLZ(1 << 30));
207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    REPORTER_ASSERT(reporter, 0 == SkCLZ(~0U));
217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkRandom rand;
237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    for (int i = 0; i < 1000; ++i) {
247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        uint32_t mask = rand.nextU();
257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // need to get some zeros for testing, but in some obscure way so the
267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        // compiler won't "see" that, and work-around calling the functions.
277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        mask >>= (mask & 31);
287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int intri = SkCLZ(mask);
297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int porta = SkCLZ_portable(mask);
307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        REPORTER_ASSERT(reporter, intri == porta);
317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic float sk_fsel(float pred, float result_ge, float result_lt) {
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return pred >= 0 ? result_ge : result_lt;
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic float fast_floor(float x) {
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//    float big = sk_fsel(x, 0x1.0p+23, -0x1.0p+23);
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    float big = sk_fsel(x, (float)(1 << 23), -(float)(1 << 23));
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (float)(x + big) - big;
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic float std_floor(float x) {
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return sk_float_floor(x);
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void test_floor_value(skiatest::Reporter* reporter, float value) {
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    float fast = fast_floor(value);
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    float std = std_floor(value);
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, std == fast);
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//    SkDebugf("value[%1.9f] std[%g] fast[%g] equal[%d]\n",
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//             value, std, fast, std == fast);
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void test_floor(skiatest::Reporter* reporter) {
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const float gVals[] = {
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        0, 1, 1.1f, 1.01f, 1.001f, 1.0001f, 1.00001f, 1.000001f, 1.0000001f
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (size_t i = 0; i < SK_ARRAY_COUNT(gVals); ++i) {
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        test_floor_value(reporter, gVals[i]);
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//        test_floor_value(reporter, -gVals[i]);
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger// test that SkMul16ShiftRound and SkMulDiv255Round return the same result
727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic void test_muldivround(skiatest::Reporter* reporter) {
737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if 0
747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // this "complete" test is too slow, so we test a random sampling of it
757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    for (int a = 0; a <= 32767; ++a) {
777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int b = 0; b <= 32767; ++b) {
787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            unsigned prod0 = SkMul16ShiftRound(a, b, 8);
797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            unsigned prod1 = SkMulDiv255Round(a, b);
807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkASSERT(prod0 == prod1);
817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkRandom rand;
867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    for (int i = 0; i < 10000; ++i) {
877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        unsigned a = rand.nextU() & 0x7FFF;
887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        unsigned b = rand.nextU() & 0x7FFF;
897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        unsigned prod0 = SkMul16ShiftRound(a, b, 8);
917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        unsigned prod1 = SkMulDiv255Round(a, b);
927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        REPORTER_ASSERT(reporter, prod0 == prod1);
947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic float float_blend(int src, int dst, float unit) {
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return dst + (src - dst) * unit;
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic int blend31(int src, int dst, int a31) {
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return dst + ((src - dst) * a31 * 2114 >> 16);
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //    return dst + ((src - dst) * a31 * 33 >> 10);
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic int blend31_slow(int src, int dst, int a31) {
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int prod = src * a31 + (31 - a31) * dst + 16;
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    prod = (prod + (prod >> 5)) >> 5;
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return prod;
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic int blend31_round(int src, int dst, int a31) {
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int prod = (src - dst) * a31 + 16;
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    prod = (prod + (prod >> 5)) >> 5;
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return dst + prod;
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic int blend31_old(int src, int dst, int a31) {
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    a31 += a31 >> 4;
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return dst + ((src - dst) * a31 >> 5);
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// suppress unused code warning
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic int (*blend_functions[])(int, int, int) = {
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    blend31,
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    blend31_slow,
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    blend31_round,
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    blend31_old
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void test_blend31() {
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int failed = 0;
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int death = 0;
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (false) { // avoid bit rot, suppress warning
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        failed = (*blend_functions[0])(0,0,0);
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int src = 0; src <= 255; src++) {
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int dst = 0; dst <= 255; dst++) {
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            for (int a = 0; a <= 31; a++) {
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//                int r0 = blend31(src, dst, a);
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//                int r0 = blend31_round(src, dst, a);
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//                int r0 = blend31_old(src, dst, a);
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                int r0 = blend31_slow(src, dst, a);
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                float f = float_blend(src, dst, a / 31.f);
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                int r1 = (int)f;
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                int r2 = SkScalarRoundToInt(SkFloatToScalar(f));
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                if (r0 != r1 && r0 != r2) {
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    printf("src:%d dst:%d a:%d result:%d float:%g\n",
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                 src, dst, a, r0, f);
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    failed += 1;
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                if (r0 > 255) {
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    death += 1;
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    printf("death src:%d dst:%d a:%d result:%d float:%g\n",
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                           src, dst, a, r0, f);
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugf("---- failed %d death %d\n", failed, death);
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void test_blend(skiatest::Reporter* reporter) {
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int src = 0; src <= 255; src++) {
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int dst = 0; dst <= 255; dst++) {
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            for (int a = 0; a <= 255; a++) {
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                int r0 = SkAlphaBlend255(src, dst, a);
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                float f1 = float_blend(src, dst, a / 255.f);
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                int r1 = SkScalarRoundToInt(SkFloatToScalar(f1));
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                if (r0 != r1) {
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    float diff = sk_float_abs(f1 - r1);
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    diff = sk_float_abs(diff - 0.5f);
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    if (diff > (1 / 255.f)) {
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        SkDebugf("src:%d dst:%d a:%d result:%d float:%g\n",
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                 src, dst, a, r0, f1);
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        REPORTER_ASSERT(reporter, false);
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    }
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if defined(SkLONGLONG)
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic int symmetric_fixmul(int a, int b) {
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int sa = SkExtractSign(a);
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int sb = SkExtractSign(b);
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    a = SkApplySign(a, sa);
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    b = SkApplySign(b, sb);
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 1
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int c = (int)(((SkLONGLONG)a * b) >> 16);
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkApplySign(c, sa ^ sb);
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkLONGLONG ab = (SkLONGLONG)a * b;
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (sa ^ sb) {
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        ab = -ab;
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return ab >> 16;
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void check_length(skiatest::Reporter* reporter,
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                         const SkPoint& p, SkScalar targetLen) {
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    float x = SkScalarToFloat(p.fX);
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    float y = SkScalarToFloat(p.fY);
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    float len = sk_float_sqrt(x*x + y*y);
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    len /= SkScalarToFloat(targetLen);
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, len > 0.999f && len < 1.001f);
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
222096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerstatic float nextFloat(SkMWCRandom& rand) {
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkFloatIntUnion data;
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    data.fSignBitInt = rand.nextU();
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return data.fFloat;
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*  returns true if a == b as resulting from (int)x. Since it is undefined
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru what to do if the float exceeds 2^32-1, we check for that explicitly.
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic bool equal_float_native_skia(float x, uint32_t ni, uint32_t si) {
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!(x == x)) {    // NAN
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return ((int32_t)si) == SK_MaxS32 || ((int32_t)si) == SK_MinS32;
23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // for out of range, C is undefined, but skia always should return NaN32
23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (x > SK_MaxS32) {
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return ((int32_t)si) == SK_MaxS32;
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (x < -SK_MaxS32) {
24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return ((int32_t)si) == SK_MinS32;
24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return si == ni;
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void assert_float_equal(skiatest::Reporter* reporter, const char op[],
24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                               float x, uint32_t ni, uint32_t si) {
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!equal_float_native_skia(x, ni, si)) {
24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkString desc;
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t xi = SkFloat2Bits(x);
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        desc.printf("%s float %g bits %x native %x skia %x\n", op, x, xi, ni, si);
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        reporter->reportFailed(desc);
25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void test_float_cast(skiatest::Reporter* reporter, float x) {
25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int ix = (int)x;
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int iix = SkFloatToIntCast(x);
25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    assert_float_equal(reporter, "cast", x, ix, iix);
25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void test_float_floor(skiatest::Reporter* reporter, float x) {
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int ix = (int)floor(x);
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int iix = SkFloatToIntFloor(x);
26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    assert_float_equal(reporter, "floor", x, ix, iix);
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void test_float_round(skiatest::Reporter* reporter, float x) {
26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    double xx = x + 0.5;    // need intermediate double to avoid temp loss
26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int ix = (int)floor(xx);
27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int iix = SkFloatToIntRound(x);
27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    assert_float_equal(reporter, "round", x, ix, iix);
27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void test_float_ceil(skiatest::Reporter* reporter, float x) {
27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int ix = (int)ceil(x);
27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int iix = SkFloatToIntCeil(x);
27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    assert_float_equal(reporter, "ceil", x, ix, iix);
27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void test_float_conversions(skiatest::Reporter* reporter, float x) {
28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    test_float_cast(reporter, x);
28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    test_float_floor(reporter, x);
28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    test_float_round(reporter, x);
28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    test_float_ceil(reporter, x);
28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void test_int2float(skiatest::Reporter* reporter, int ival) {
28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    float x0 = (float)ival;
28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    float x1 = SkIntToFloatCast(ival);
29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    float x2 = SkIntToFloatCast_NoOverflowCheck(ival);
29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, x0 == x1);
29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, x0 == x2);
29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void unittest_fastfloat(skiatest::Reporter* reporter) {
296096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkMWCRandom rand;
29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t i;
29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const float gFloats[] = {
30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        0.f, 1.f, 0.5f, 0.499999f, 0.5000001f, 1.f/3,
30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        0.000000001f, 1000000000.f,     // doesn't overflow
30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        0.0000000001f, 10000000000.f    // does overflow
30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (i = 0; i < SK_ARRAY_COUNT(gFloats); i++) {
30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        test_float_conversions(reporter, gFloats[i]);
30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        test_float_conversions(reporter, -gFloats[i]);
30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int outer = 0; outer < 100; outer++) {
31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        rand.setSeed(outer);
31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (i = 0; i < 100000; i++) {
31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            float x = nextFloat(rand);
31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            test_float_conversions(reporter, x);
31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        test_int2float(reporter, 0);
31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        test_int2float(reporter, 1);
31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        test_int2float(reporter, -1);
31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (i = 0; i < 100000; i++) {
32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            // for now only test ints that are 24bits or less, since we don't
32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            // round (down) large ints the same as IEEE...
32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            int ival = rand.nextU() & 0xFFFFFF;
32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            test_int2float(reporter, ival);
32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            test_int2float(reporter, -ival);
32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FLOAT
33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic float make_zero() {
33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return sk_float_sin(0);
33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void unittest_isfinite(skiatest::Reporter* reporter) {
33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FLOAT
33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    float nan = sk_float_asin(2);
33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    float inf = 1.0f / make_zero();
33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    float big = 3.40282e+038f;
34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, !SkScalarIsNaN(inf));
34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, !SkScalarIsNaN(-inf));
34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, !SkScalarIsFinite(inf));
34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, !SkScalarIsFinite(-inf));
34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else
34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkFixed nan = SK_FixedNaN;
34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkFixed big = SK_FixedMax;
34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter,  SkScalarIsNaN(nan));
35180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, !SkScalarIsNaN(big));
35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, !SkScalarIsNaN(-big));
35380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, !SkScalarIsNaN(0));
35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
35580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, !SkScalarIsFinite(nan));
35680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter,  SkScalarIsFinite(big));
35780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter,  SkScalarIsFinite(-big));
35880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter,  SkScalarIsFinite(0));
35980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
36080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
36180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void test_muldiv255(skiatest::Reporter* reporter) {
36280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int a = 0; a <= 255; a++) {
36380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int b = 0; b <= 255; b++) {
36480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            int ab = a * b;
36580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            float s = ab / 255.0f;
36680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            int round = (int)floorf(s + 0.5f);
36780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            int trunc = (int)floorf(s);
36880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
36980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            int iround = SkMulDiv255Round(a, b);
37080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            int itrunc = SkMulDiv255Trunc(a, b);
37180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            REPORTER_ASSERT(reporter, iround == round);
37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            REPORTER_ASSERT(reporter, itrunc == trunc);
37480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
37580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            REPORTER_ASSERT(reporter, itrunc <= iround);
37680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            REPORTER_ASSERT(reporter, iround <= a);
37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            REPORTER_ASSERT(reporter, iround <= b);
37880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
37980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
38080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
38180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void test_muldiv255ceiling(skiatest::Reporter* reporter) {
38380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int c = 0; c <= 255; c++) {
38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int a = 0; a <= 255; a++) {
38580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            int product = (c * a + 255);
38680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            int expected_ceiling = (product + (product >> 8)) >> 8;
38780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            int webkit_ceiling = (c * a + 254) / 255;
38880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            REPORTER_ASSERT(reporter, expected_ceiling == webkit_ceiling);
38980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            int skia_ceiling = SkMulDiv255Ceiling(c, a);
39080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            REPORTER_ASSERT(reporter, skia_ceiling == webkit_ceiling);
39180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
39480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
39580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void test_copysign(skiatest::Reporter* reporter) {
39680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const int32_t gTriples[] = {
39780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // x, y, expected result
39880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        0, 0, 0,
39980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        0, 1, 0,
40080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        0, -1, 0,
40180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        1, 0, 1,
40280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        1, 1, 1,
40380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        1, -1, -1,
40480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        -1, 0, 1,
40580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        -1, 1, 1,
40680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        -1, -1, -1,
40780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
40880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (size_t i = 0; i < SK_ARRAY_COUNT(gTriples); i += 3) {
40980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter,
41080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        SkCopySign32(gTriples[i], gTriples[i+1]) == gTriples[i+2]);
41180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        float x = (float)gTriples[i];
41280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        float y = (float)gTriples[i+1];
41380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        float expected = (float)gTriples[i+2];
41480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, sk_float_copysign(x, y) == expected);
41580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
41680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
417096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkMWCRandom rand;
41880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int j = 0; j < 1000; j++) {
41980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int ix = rand.nextS();
42080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, SkCopySign32(ix, ix) == ix);
42180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, SkCopySign32(ix, -ix) == -ix);
42280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, SkCopySign32(-ix, ix) == ix);
42380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, SkCopySign32(-ix, -ix) == -ix);
42480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
42580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkScalar sx = rand.nextSScalar1();
42680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, SkScalarCopySign(sx, sx) == sx);
42780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, SkScalarCopySign(sx, -sx) == -sx);
42880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, SkScalarCopySign(-sx, sx) == sx);
42980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, SkScalarCopySign(-sx, -sx) == -sx);
43080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
43180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
43280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
43380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void TestMath(skiatest::Reporter* reporter) {
43480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int         i;
43580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int32_t     x;
436096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkMWCRandom    rand;
43780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
43880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // these should assert
43980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0
44080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkToS8(128);
44180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkToS8(-129);
44280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkToU8(256);
44380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkToU8(-5);
44480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
44580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkToS16(32768);
44680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkToS16(-32769);
44780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkToU16(65536);
44880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkToU16(-5);
44980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
45080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (sizeof(size_t) > 4) {
45180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkToS32(4*1024*1024);
45280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkToS32(-4*1024*1024);
45380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkToU32(5*1024*1024);
45480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkToU32(-5);
45580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
45680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
45780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
45880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    test_muldiv255(reporter);
45980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    test_muldiv255ceiling(reporter);
46080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    test_copysign(reporter);
46180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
46280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
46380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkScalar x = SK_ScalarNaN;
46480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, SkScalarIsNaN(x));
46580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
46680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
46780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (i = 1; i <= 10; i++) {
46880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        x = SkCubeRootBits(i*i*i, 11);
46980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, x == i);
47080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
47180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
47280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    x = SkFixedSqrt(SK_Fixed1);
47380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, x == SK_Fixed1);
47480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    x = SkFixedSqrt(SK_Fixed1/4);
47580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, x == SK_Fixed1/2);
47680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    x = SkFixedSqrt(SK_Fixed1*4);
47780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, x == SK_Fixed1*2);
47880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
47980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    x = SkFractSqrt(SK_Fract1);
48080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, x == SK_Fract1);
48180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    x = SkFractSqrt(SK_Fract1/4);
48280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, x == SK_Fract1/2);
48380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    x = SkFractSqrt(SK_Fract1/16);
48480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, x == SK_Fract1/4);
48580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
48680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (i = 1; i < 100; i++) {
48780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        x = SkFixedSqrt(SK_Fixed1 * i * i);
48880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, x == SK_Fixed1 * i);
48980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
49080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
49180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (i = 0; i < 1000; i++) {
49280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int value = rand.nextS16();
49380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int max = rand.nextU16();
49480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
49580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int clamp = SkClampMax(value, max);
49680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int clamp2 = value < 0 ? 0 : (value > max ? max : value);
49780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, clamp == clamp2);
49880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
49980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
50080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (i = 0; i < 10000; i++) {
50180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkPoint p;
50280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
50380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // These random values are being treated as 32-bit-patterns, not as
50480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // ints; calling SkIntToScalar() here produces crashes.
50580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        p.setLength((SkScalar) rand.nextS(),
50680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    (SkScalar) rand.nextS(),
50780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    SK_Scalar1);
50880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        check_length(reporter, p, SK_Scalar1);
50980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        p.setLength((SkScalar) (rand.nextS() >> 13),
51080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    (SkScalar) (rand.nextS() >> 13),
51180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    SK_Scalar1);
51280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        check_length(reporter, p, SK_Scalar1);
51380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
51480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
51580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
51680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkFixed result = SkFixedDiv(100, 100);
51780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, result == SK_Fixed1);
51880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        result = SkFixedDiv(1, SK_Fixed1);
51980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, result == 1);
52080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
52180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
52280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unittest_fastfloat(reporter);
52380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unittest_isfinite(reporter);
52480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
52580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SkLONGLONG
52680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (i = 0; i < 10000; i++) {
52780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkFixed numer = rand.nextS();
52880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkFixed denom = rand.nextS();
52980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkFixed result = SkFixedDiv(numer, denom);
53080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkLONGLONG check = ((SkLONGLONG)numer << 16) / denom;
53180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
53280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        (void)SkCLZ(numer);
53380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        (void)SkCLZ(denom);
53480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
53580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, result != (SkFixed)SK_NaN32);
53680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (check > SK_MaxS32) {
53780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            check = SK_MaxS32;
53880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else if (check < -SK_MaxS32) {
53980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            check = SK_MinS32;
54080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
54180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, result == (int32_t)check);
54280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
54380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        result = SkFractDiv(numer, denom);
54480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        check = ((SkLONGLONG)numer << 30) / denom;
54580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
54680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, result != (SkFixed)SK_NaN32);
54780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (check > SK_MaxS32) {
54880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            check = SK_MaxS32;
54980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else if (check < -SK_MaxS32) {
55080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            check = SK_MinS32;
55180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
55280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, result == (int32_t)check);
55380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
55480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // make them <= 2^24, so we don't overflow in fixmul
55580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        numer = numer << 8 >> 8;
55680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        denom = denom << 8 >> 8;
55780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
55880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        result = SkFixedMul(numer, denom);
55980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkFixed r2 = symmetric_fixmul(numer, denom);
56080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        //        SkASSERT(result == r2);
56180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
56280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        result = SkFixedMul(numer, numer);
56380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        r2 = SkFixedSquare(numer);
56480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, result == r2);
56580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
56680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (numer >= 0 && denom >= 0) {
56780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkFixed mean = SkFixedMean(numer, denom);
56880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            float prod = SkFixedToFloat(numer) * SkFixedToFloat(denom);
56980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            float fm = sk_float_sqrt(sk_float_abs(prod));
57080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkFixed mean2 = SkFloatToFixed(fm);
57180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            int diff = SkAbs32(mean - mean2);
57280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            REPORTER_ASSERT(reporter, diff <= 1);
57380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
57480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
57580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        {
57680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkFixed mod = SkFixedMod(numer, denom);
57780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            float n = SkFixedToFloat(numer);
57880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            float d = SkFixedToFloat(denom);
57980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            float m = sk_float_mod(n, d);
58080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            // ensure the same sign
58180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            REPORTER_ASSERT(reporter, mod == 0 || (mod < 0) == (m < 0));
58280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            int diff = SkAbs32(mod - SkFloatToFixed(m));
58380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            REPORTER_ASSERT(reporter, (diff >> 7) == 0);
58480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
58580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
58680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
58780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
58880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (i = 0; i < 10000; i++) {
58980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkFract x = rand.nextU() >> 1;
59080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        double xx = (double)x / SK_Fract1;
59180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkFract xr = SkFractSqrt(x);
59280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkFract check = SkFloatToFract(sqrt(xx));
59380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, xr == check ||
59480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                  xr == check-1 ||
59580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                  xr == check+1);
59680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
59780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        xr = SkFixedSqrt(x);
59880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        xx = (double)x / SK_Fixed1;
59980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        check = SkFloatToFixed(sqrt(xx));
60080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, xr == check || xr == check-1);
60180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
60280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        xr = SkSqrt32(x);
60380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        xx = (double)x;
60480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        check = (int32_t)sqrt(xx);
60580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, xr == check || xr == check-1);
60680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
60780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
60880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if !defined(SK_SCALAR_IS_FLOAT)
60980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
61080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkFixed s, c;
61180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        s = SkFixedSinCos(0, &c);
61280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, s == 0);
61380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        REPORTER_ASSERT(reporter, c == SK_Fixed1);
61480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
61580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
61680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int maxDiff = 0;
61780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (i = 0; i < 1000; i++) {
61880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkFixed rads = rand.nextS() >> 10;
61980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        double frads = SkFixedToFloat(rads);
62080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
62180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkFixed s, c;
62280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        s = SkScalarSinCos(rads, &c);
62380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
62480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        double fs = sin(frads);
62580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        double fc = cos(frads);
62680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
62780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkFixed is = SkFloatToFixed(fs);
62880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkFixed ic = SkFloatToFixed(fc);
62980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
63080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        maxDiff = SkMax32(maxDiff, SkAbs32(is - s));
63180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        maxDiff = SkMax32(maxDiff, SkAbs32(ic - c));
63280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
63380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugf("SinCos: maximum error = %d\n", maxDiff);
63480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
63580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
63680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FLOAT
63780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    test_blend(reporter);
63880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
63980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
640d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    if (false) test_floor(reporter);
64180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
64280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // disable for now
64380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (false) test_blend31();  // avoid bit rot, suppress warning
6447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    test_muldivround(reporter);
6467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    test_clz(reporter);
64780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
64880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
64980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "TestClassDef.h"
65080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruDEFINE_TESTCLASS("Math", MathTestClass, TestMath)
6517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
6537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkEndian.h"
6557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergertemplate <typename T> struct PairRec {
6577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    T   fYin;
6587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    T   fYang;
6597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
6607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic void TestEndian(skiatest::Reporter* reporter) {
6627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    static const PairRec<uint16_t> g16[] = {
6637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        { 0x0,      0x0     },
6647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        { 0xFFFF,   0xFFFF  },
6657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        { 0x1122,   0x2211  },
6667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
6677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    static const PairRec<uint32_t> g32[] = {
6687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        { 0x0,          0x0         },
6697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        { 0xFFFFFFFF,   0xFFFFFFFF  },
6707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        { 0x11223344,   0x44332211  },
6717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
6727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    static const PairRec<uint64_t> g64[] = {
6737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        { 0x0,      0x0                             },
6747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        { 0xFFFFFFFFFFFFFFFFULL,  0xFFFFFFFFFFFFFFFFULL  },
6757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        { 0x1122334455667788ULL,  0x8877665544332211ULL  },
6767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    };
6777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    REPORTER_ASSERT(reporter, 0x1122 == SkTEndianSwap16<0x2211>::value);
6797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    REPORTER_ASSERT(reporter, 0x11223344 == SkTEndianSwap32<0x44332211>::value);
6807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    REPORTER_ASSERT(reporter, 0x1122334455667788ULL == SkTEndianSwap64<0x8877665544332211ULL>::value);
6817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    for (size_t i = 0; i < SK_ARRAY_COUNT(g16); ++i) {
6837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        REPORTER_ASSERT(reporter, g16[i].fYang == SkEndianSwap16(g16[i].fYin));
6847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    for (size_t i = 0; i < SK_ARRAY_COUNT(g32); ++i) {
6867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        REPORTER_ASSERT(reporter, g32[i].fYang == SkEndianSwap32(g32[i].fYin));
6877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    for (size_t i = 0; i < SK_ARRAY_COUNT(g64); ++i) {
6897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        REPORTER_ASSERT(reporter, g64[i].fYang == SkEndianSwap64(g64[i].fYin));
6907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
6917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
6927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerDEFINE_TESTCLASS("Endian", EndianTestClass, TestEndian)
694