Home | History | Annotate | Download | only in tests
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 #include "Test.h"
      9 #include "SkFloatBits.h"
     10 #include "SkFloatingPoint.h"
     11 #include "SkMathPriv.h"
     12 #include "SkPoint.h"
     13 #include "SkRandom.h"
     14 #include "SkColorPriv.h"
     15 
     16 static void test_clz(skiatest::Reporter* reporter) {
     17     REPORTER_ASSERT(reporter, 32 == SkCLZ(0));
     18     REPORTER_ASSERT(reporter, 31 == SkCLZ(1));
     19     REPORTER_ASSERT(reporter, 1 == SkCLZ(1 << 30));
     20     REPORTER_ASSERT(reporter, 0 == SkCLZ(~0U));
     21 
     22     SkRandom rand;
     23     for (int i = 0; i < 1000; ++i) {
     24         uint32_t mask = rand.nextU();
     25         // need to get some zeros for testing, but in some obscure way so the
     26         // compiler won't "see" that, and work-around calling the functions.
     27         mask >>= (mask & 31);
     28         int intri = SkCLZ(mask);
     29         int porta = SkCLZ_portable(mask);
     30         REPORTER_ASSERT(reporter, intri == porta);
     31     }
     32 }
     33 
     34 ///////////////////////////////////////////////////////////////////////////////
     35 
     36 static float sk_fsel(float pred, float result_ge, float result_lt) {
     37     return pred >= 0 ? result_ge : result_lt;
     38 }
     39 
     40 static float fast_floor(float x) {
     41 //    float big = sk_fsel(x, 0x1.0p+23, -0x1.0p+23);
     42     float big = sk_fsel(x, (float)(1 << 23), -(float)(1 << 23));
     43     return (float)(x + big) - big;
     44 }
     45 
     46 static float std_floor(float x) {
     47     return sk_float_floor(x);
     48 }
     49 
     50 static void test_floor_value(skiatest::Reporter* reporter, float value) {
     51     float fast = fast_floor(value);
     52     float std = std_floor(value);
     53     REPORTER_ASSERT(reporter, std == fast);
     54 //    SkDebugf("value[%1.9f] std[%g] fast[%g] equal[%d]\n",
     55 //             value, std, fast, std == fast);
     56 }
     57 
     58 static void test_floor(skiatest::Reporter* reporter) {
     59     static const float gVals[] = {
     60         0, 1, 1.1f, 1.01f, 1.001f, 1.0001f, 1.00001f, 1.000001f, 1.0000001f
     61     };
     62 
     63     for (size_t i = 0; i < SK_ARRAY_COUNT(gVals); ++i) {
     64         test_floor_value(reporter, gVals[i]);
     65 //        test_floor_value(reporter, -gVals[i]);
     66     }
     67 }
     68 
     69 ///////////////////////////////////////////////////////////////////////////////
     70 
     71 // test that SkMul16ShiftRound and SkMulDiv255Round return the same result
     72 static void test_muldivround(skiatest::Reporter* reporter) {
     73 #if 0
     74     // this "complete" test is too slow, so we test a random sampling of it
     75 
     76     for (int a = 0; a <= 32767; ++a) {
     77         for (int b = 0; b <= 32767; ++b) {
     78             unsigned prod0 = SkMul16ShiftRound(a, b, 8);
     79             unsigned prod1 = SkMulDiv255Round(a, b);
     80             SkASSERT(prod0 == prod1);
     81         }
     82     }
     83 #endif
     84 
     85     SkRandom rand;
     86     for (int i = 0; i < 10000; ++i) {
     87         unsigned a = rand.nextU() & 0x7FFF;
     88         unsigned b = rand.nextU() & 0x7FFF;
     89 
     90         unsigned prod0 = SkMul16ShiftRound(a, b, 8);
     91         unsigned prod1 = SkMulDiv255Round(a, b);
     92 
     93         REPORTER_ASSERT(reporter, prod0 == prod1);
     94     }
     95 }
     96 
     97 static float float_blend(int src, int dst, float unit) {
     98     return dst + (src - dst) * unit;
     99 }
    100 
    101 static int blend31(int src, int dst, int a31) {
    102     return dst + ((src - dst) * a31 * 2114 >> 16);
    103     //    return dst + ((src - dst) * a31 * 33 >> 10);
    104 }
    105 
    106 static int blend31_slow(int src, int dst, int a31) {
    107     int prod = src * a31 + (31 - a31) * dst + 16;
    108     prod = (prod + (prod >> 5)) >> 5;
    109     return prod;
    110 }
    111 
    112 static int blend31_round(int src, int dst, int a31) {
    113     int prod = (src - dst) * a31 + 16;
    114     prod = (prod + (prod >> 5)) >> 5;
    115     return dst + prod;
    116 }
    117 
    118 static int blend31_old(int src, int dst, int a31) {
    119     a31 += a31 >> 4;
    120     return dst + ((src - dst) * a31 >> 5);
    121 }
    122 
    123 // suppress unused code warning
    124 static int (*blend_functions[])(int, int, int) = {
    125     blend31,
    126     blend31_slow,
    127     blend31_round,
    128     blend31_old
    129 };
    130 
    131 static void test_blend31() {
    132     int failed = 0;
    133     int death = 0;
    134     if (false) { // avoid bit rot, suppress warning
    135         failed = (*blend_functions[0])(0,0,0);
    136     }
    137     for (int src = 0; src <= 255; src++) {
    138         for (int dst = 0; dst <= 255; dst++) {
    139             for (int a = 0; a <= 31; a++) {
    140 //                int r0 = blend31(src, dst, a);
    141 //                int r0 = blend31_round(src, dst, a);
    142 //                int r0 = blend31_old(src, dst, a);
    143                 int r0 = blend31_slow(src, dst, a);
    144 
    145                 float f = float_blend(src, dst, a / 31.f);
    146                 int r1 = (int)f;
    147                 int r2 = SkScalarRoundToInt(SkFloatToScalar(f));
    148 
    149                 if (r0 != r1 && r0 != r2) {
    150                     printf("src:%d dst:%d a:%d result:%d float:%g\n",
    151                                  src, dst, a, r0, f);
    152                     failed += 1;
    153                 }
    154                 if (r0 > 255) {
    155                     death += 1;
    156                     printf("death src:%d dst:%d a:%d result:%d float:%g\n",
    157                            src, dst, a, r0, f);
    158                 }
    159             }
    160         }
    161     }
    162     SkDebugf("---- failed %d death %d\n", failed, death);
    163 }
    164 
    165 static void test_blend(skiatest::Reporter* reporter) {
    166     for (int src = 0; src <= 255; src++) {
    167         for (int dst = 0; dst <= 255; dst++) {
    168             for (int a = 0; a <= 255; a++) {
    169                 int r0 = SkAlphaBlend255(src, dst, a);
    170                 float f1 = float_blend(src, dst, a / 255.f);
    171                 int r1 = SkScalarRoundToInt(SkFloatToScalar(f1));
    172 
    173                 if (r0 != r1) {
    174                     float diff = sk_float_abs(f1 - r1);
    175                     diff = sk_float_abs(diff - 0.5f);
    176                     if (diff > (1 / 255.f)) {
    177 #ifdef SK_DEBUG
    178                         SkDebugf("src:%d dst:%d a:%d result:%d float:%g\n",
    179                                  src, dst, a, r0, f1);
    180 #endif
    181                         REPORTER_ASSERT(reporter, false);
    182                     }
    183                 }
    184             }
    185         }
    186     }
    187 }
    188 
    189 #if defined(SkLONGLONG)
    190 static int symmetric_fixmul(int a, int b) {
    191     int sa = SkExtractSign(a);
    192     int sb = SkExtractSign(b);
    193 
    194     a = SkApplySign(a, sa);
    195     b = SkApplySign(b, sb);
    196 
    197 #if 1
    198     int c = (int)(((SkLONGLONG)a * b) >> 16);
    199 
    200     return SkApplySign(c, sa ^ sb);
    201 #else
    202     SkLONGLONG ab = (SkLONGLONG)a * b;
    203     if (sa ^ sb) {
    204         ab = -ab;
    205     }
    206     return ab >> 16;
    207 #endif
    208 }
    209 #endif
    210 
    211 static void check_length(skiatest::Reporter* reporter,
    212                          const SkPoint& p, SkScalar targetLen) {
    213     float x = SkScalarToFloat(p.fX);
    214     float y = SkScalarToFloat(p.fY);
    215     float len = sk_float_sqrt(x*x + y*y);
    216 
    217     len /= SkScalarToFloat(targetLen);
    218 
    219     REPORTER_ASSERT(reporter, len > 0.999f && len < 1.001f);
    220 }
    221 
    222 static float nextFloat(SkMWCRandom& rand) {
    223     SkFloatIntUnion data;
    224     data.fSignBitInt = rand.nextU();
    225     return data.fFloat;
    226 }
    227 
    228 /*  returns true if a == b as resulting from (int)x. Since it is undefined
    229  what to do if the float exceeds 2^32-1, we check for that explicitly.
    230  */
    231 static bool equal_float_native_skia(float x, uint32_t ni, uint32_t si) {
    232     if (!(x == x)) {    // NAN
    233         return ((int32_t)si) == SK_MaxS32 || ((int32_t)si) == SK_MinS32;
    234     }
    235     // for out of range, C is undefined, but skia always should return NaN32
    236     if (x > SK_MaxS32) {
    237         return ((int32_t)si) == SK_MaxS32;
    238     }
    239     if (x < -SK_MaxS32) {
    240         return ((int32_t)si) == SK_MinS32;
    241     }
    242     return si == ni;
    243 }
    244 
    245 static void assert_float_equal(skiatest::Reporter* reporter, const char op[],
    246                                float x, uint32_t ni, uint32_t si) {
    247     if (!equal_float_native_skia(x, ni, si)) {
    248         SkString desc;
    249         uint32_t xi = SkFloat2Bits(x);
    250         desc.printf("%s float %g bits %x native %x skia %x\n", op, x, xi, ni, si);
    251         reporter->reportFailed(desc);
    252     }
    253 }
    254 
    255 static void test_float_cast(skiatest::Reporter* reporter, float x) {
    256     int ix = (int)x;
    257     int iix = SkFloatToIntCast(x);
    258     assert_float_equal(reporter, "cast", x, ix, iix);
    259 }
    260 
    261 static void test_float_floor(skiatest::Reporter* reporter, float x) {
    262     int ix = (int)floor(x);
    263     int iix = SkFloatToIntFloor(x);
    264     assert_float_equal(reporter, "floor", x, ix, iix);
    265 }
    266 
    267 static void test_float_round(skiatest::Reporter* reporter, float x) {
    268     double xx = x + 0.5;    // need intermediate double to avoid temp loss
    269     int ix = (int)floor(xx);
    270     int iix = SkFloatToIntRound(x);
    271     assert_float_equal(reporter, "round", x, ix, iix);
    272 }
    273 
    274 static void test_float_ceil(skiatest::Reporter* reporter, float x) {
    275     int ix = (int)ceil(x);
    276     int iix = SkFloatToIntCeil(x);
    277     assert_float_equal(reporter, "ceil", x, ix, iix);
    278 }
    279 
    280 static void test_float_conversions(skiatest::Reporter* reporter, float x) {
    281     test_float_cast(reporter, x);
    282     test_float_floor(reporter, x);
    283     test_float_round(reporter, x);
    284     test_float_ceil(reporter, x);
    285 }
    286 
    287 static void test_int2float(skiatest::Reporter* reporter, int ival) {
    288     float x0 = (float)ival;
    289     float x1 = SkIntToFloatCast(ival);
    290     float x2 = SkIntToFloatCast_NoOverflowCheck(ival);
    291     REPORTER_ASSERT(reporter, x0 == x1);
    292     REPORTER_ASSERT(reporter, x0 == x2);
    293 }
    294 
    295 static void unittest_fastfloat(skiatest::Reporter* reporter) {
    296     SkMWCRandom rand;
    297     size_t i;
    298 
    299     static const float gFloats[] = {
    300         0.f, 1.f, 0.5f, 0.499999f, 0.5000001f, 1.f/3,
    301         0.000000001f, 1000000000.f,     // doesn't overflow
    302         0.0000000001f, 10000000000.f    // does overflow
    303     };
    304     for (i = 0; i < SK_ARRAY_COUNT(gFloats); i++) {
    305         test_float_conversions(reporter, gFloats[i]);
    306         test_float_conversions(reporter, -gFloats[i]);
    307     }
    308 
    309     for (int outer = 0; outer < 100; outer++) {
    310         rand.setSeed(outer);
    311         for (i = 0; i < 100000; i++) {
    312             float x = nextFloat(rand);
    313             test_float_conversions(reporter, x);
    314         }
    315 
    316         test_int2float(reporter, 0);
    317         test_int2float(reporter, 1);
    318         test_int2float(reporter, -1);
    319         for (i = 0; i < 100000; i++) {
    320             // for now only test ints that are 24bits or less, since we don't
    321             // round (down) large ints the same as IEEE...
    322             int ival = rand.nextU() & 0xFFFFFF;
    323             test_int2float(reporter, ival);
    324             test_int2float(reporter, -ival);
    325         }
    326     }
    327 }
    328 
    329 #ifdef SK_SCALAR_IS_FLOAT
    330 static float make_zero() {
    331     return sk_float_sin(0);
    332 }
    333 #endif
    334 
    335 static void unittest_isfinite(skiatest::Reporter* reporter) {
    336 #ifdef SK_SCALAR_IS_FLOAT
    337     float nan = sk_float_asin(2);
    338     float inf = 1.0f / make_zero();
    339     float big = 3.40282e+038f;
    340 
    341     REPORTER_ASSERT(reporter, !SkScalarIsNaN(inf));
    342     REPORTER_ASSERT(reporter, !SkScalarIsNaN(-inf));
    343     REPORTER_ASSERT(reporter, !SkScalarIsFinite(inf));
    344     REPORTER_ASSERT(reporter, !SkScalarIsFinite(-inf));
    345 #else
    346     SkFixed nan = SK_FixedNaN;
    347     SkFixed big = SK_FixedMax;
    348 #endif
    349 
    350     REPORTER_ASSERT(reporter,  SkScalarIsNaN(nan));
    351     REPORTER_ASSERT(reporter, !SkScalarIsNaN(big));
    352     REPORTER_ASSERT(reporter, !SkScalarIsNaN(-big));
    353     REPORTER_ASSERT(reporter, !SkScalarIsNaN(0));
    354 
    355     REPORTER_ASSERT(reporter, !SkScalarIsFinite(nan));
    356     REPORTER_ASSERT(reporter,  SkScalarIsFinite(big));
    357     REPORTER_ASSERT(reporter,  SkScalarIsFinite(-big));
    358     REPORTER_ASSERT(reporter,  SkScalarIsFinite(0));
    359 }
    360 
    361 static void test_muldiv255(skiatest::Reporter* reporter) {
    362     for (int a = 0; a <= 255; a++) {
    363         for (int b = 0; b <= 255; b++) {
    364             int ab = a * b;
    365             float s = ab / 255.0f;
    366             int round = (int)floorf(s + 0.5f);
    367             int trunc = (int)floorf(s);
    368 
    369             int iround = SkMulDiv255Round(a, b);
    370             int itrunc = SkMulDiv255Trunc(a, b);
    371 
    372             REPORTER_ASSERT(reporter, iround == round);
    373             REPORTER_ASSERT(reporter, itrunc == trunc);
    374 
    375             REPORTER_ASSERT(reporter, itrunc <= iround);
    376             REPORTER_ASSERT(reporter, iround <= a);
    377             REPORTER_ASSERT(reporter, iround <= b);
    378         }
    379     }
    380 }
    381 
    382 static void test_muldiv255ceiling(skiatest::Reporter* reporter) {
    383     for (int c = 0; c <= 255; c++) {
    384         for (int a = 0; a <= 255; a++) {
    385             int product = (c * a + 255);
    386             int expected_ceiling = (product + (product >> 8)) >> 8;
    387             int webkit_ceiling = (c * a + 254) / 255;
    388             REPORTER_ASSERT(reporter, expected_ceiling == webkit_ceiling);
    389             int skia_ceiling = SkMulDiv255Ceiling(c, a);
    390             REPORTER_ASSERT(reporter, skia_ceiling == webkit_ceiling);
    391         }
    392     }
    393 }
    394 
    395 static void test_copysign(skiatest::Reporter* reporter) {
    396     static const int32_t gTriples[] = {
    397         // x, y, expected result
    398         0, 0, 0,
    399         0, 1, 0,
    400         0, -1, 0,
    401         1, 0, 1,
    402         1, 1, 1,
    403         1, -1, -1,
    404         -1, 0, 1,
    405         -1, 1, 1,
    406         -1, -1, -1,
    407     };
    408     for (size_t i = 0; i < SK_ARRAY_COUNT(gTriples); i += 3) {
    409         REPORTER_ASSERT(reporter,
    410                         SkCopySign32(gTriples[i], gTriples[i+1]) == gTriples[i+2]);
    411         float x = (float)gTriples[i];
    412         float y = (float)gTriples[i+1];
    413         float expected = (float)gTriples[i+2];
    414         REPORTER_ASSERT(reporter, sk_float_copysign(x, y) == expected);
    415     }
    416 
    417     SkMWCRandom rand;
    418     for (int j = 0; j < 1000; j++) {
    419         int ix = rand.nextS();
    420         REPORTER_ASSERT(reporter, SkCopySign32(ix, ix) == ix);
    421         REPORTER_ASSERT(reporter, SkCopySign32(ix, -ix) == -ix);
    422         REPORTER_ASSERT(reporter, SkCopySign32(-ix, ix) == ix);
    423         REPORTER_ASSERT(reporter, SkCopySign32(-ix, -ix) == -ix);
    424 
    425         SkScalar sx = rand.nextSScalar1();
    426         REPORTER_ASSERT(reporter, SkScalarCopySign(sx, sx) == sx);
    427         REPORTER_ASSERT(reporter, SkScalarCopySign(sx, -sx) == -sx);
    428         REPORTER_ASSERT(reporter, SkScalarCopySign(-sx, sx) == sx);
    429         REPORTER_ASSERT(reporter, SkScalarCopySign(-sx, -sx) == -sx);
    430     }
    431 }
    432 
    433 static void TestMath(skiatest::Reporter* reporter) {
    434     int         i;
    435     int32_t     x;
    436     SkMWCRandom    rand;
    437 
    438     // these should assert
    439 #if 0
    440     SkToS8(128);
    441     SkToS8(-129);
    442     SkToU8(256);
    443     SkToU8(-5);
    444 
    445     SkToS16(32768);
    446     SkToS16(-32769);
    447     SkToU16(65536);
    448     SkToU16(-5);
    449 
    450     if (sizeof(size_t) > 4) {
    451         SkToS32(4*1024*1024);
    452         SkToS32(-4*1024*1024);
    453         SkToU32(5*1024*1024);
    454         SkToU32(-5);
    455     }
    456 #endif
    457 
    458     test_muldiv255(reporter);
    459     test_muldiv255ceiling(reporter);
    460     test_copysign(reporter);
    461 
    462     {
    463         SkScalar x = SK_ScalarNaN;
    464         REPORTER_ASSERT(reporter, SkScalarIsNaN(x));
    465     }
    466 
    467     for (i = 1; i <= 10; i++) {
    468         x = SkCubeRootBits(i*i*i, 11);
    469         REPORTER_ASSERT(reporter, x == i);
    470     }
    471 
    472     x = SkFixedSqrt(SK_Fixed1);
    473     REPORTER_ASSERT(reporter, x == SK_Fixed1);
    474     x = SkFixedSqrt(SK_Fixed1/4);
    475     REPORTER_ASSERT(reporter, x == SK_Fixed1/2);
    476     x = SkFixedSqrt(SK_Fixed1*4);
    477     REPORTER_ASSERT(reporter, x == SK_Fixed1*2);
    478 
    479     x = SkFractSqrt(SK_Fract1);
    480     REPORTER_ASSERT(reporter, x == SK_Fract1);
    481     x = SkFractSqrt(SK_Fract1/4);
    482     REPORTER_ASSERT(reporter, x == SK_Fract1/2);
    483     x = SkFractSqrt(SK_Fract1/16);
    484     REPORTER_ASSERT(reporter, x == SK_Fract1/4);
    485 
    486     for (i = 1; i < 100; i++) {
    487         x = SkFixedSqrt(SK_Fixed1 * i * i);
    488         REPORTER_ASSERT(reporter, x == SK_Fixed1 * i);
    489     }
    490 
    491     for (i = 0; i < 1000; i++) {
    492         int value = rand.nextS16();
    493         int max = rand.nextU16();
    494 
    495         int clamp = SkClampMax(value, max);
    496         int clamp2 = value < 0 ? 0 : (value > max ? max : value);
    497         REPORTER_ASSERT(reporter, clamp == clamp2);
    498     }
    499 
    500     for (i = 0; i < 10000; i++) {
    501         SkPoint p;
    502 
    503         // These random values are being treated as 32-bit-patterns, not as
    504         // ints; calling SkIntToScalar() here produces crashes.
    505         p.setLength((SkScalar) rand.nextS(),
    506                     (SkScalar) rand.nextS(),
    507                     SK_Scalar1);
    508         check_length(reporter, p, SK_Scalar1);
    509         p.setLength((SkScalar) (rand.nextS() >> 13),
    510                     (SkScalar) (rand.nextS() >> 13),
    511                     SK_Scalar1);
    512         check_length(reporter, p, SK_Scalar1);
    513     }
    514 
    515     {
    516         SkFixed result = SkFixedDiv(100, 100);
    517         REPORTER_ASSERT(reporter, result == SK_Fixed1);
    518         result = SkFixedDiv(1, SK_Fixed1);
    519         REPORTER_ASSERT(reporter, result == 1);
    520     }
    521 
    522     unittest_fastfloat(reporter);
    523     unittest_isfinite(reporter);
    524 
    525 #ifdef SkLONGLONG
    526     for (i = 0; i < 10000; i++) {
    527         SkFixed numer = rand.nextS();
    528         SkFixed denom = rand.nextS();
    529         SkFixed result = SkFixedDiv(numer, denom);
    530         SkLONGLONG check = ((SkLONGLONG)numer << 16) / denom;
    531 
    532         (void)SkCLZ(numer);
    533         (void)SkCLZ(denom);
    534 
    535         REPORTER_ASSERT(reporter, result != (SkFixed)SK_NaN32);
    536         if (check > SK_MaxS32) {
    537             check = SK_MaxS32;
    538         } else if (check < -SK_MaxS32) {
    539             check = SK_MinS32;
    540         }
    541         REPORTER_ASSERT(reporter, result == (int32_t)check);
    542 
    543         result = SkFractDiv(numer, denom);
    544         check = ((SkLONGLONG)numer << 30) / denom;
    545 
    546         REPORTER_ASSERT(reporter, result != (SkFixed)SK_NaN32);
    547         if (check > SK_MaxS32) {
    548             check = SK_MaxS32;
    549         } else if (check < -SK_MaxS32) {
    550             check = SK_MinS32;
    551         }
    552         REPORTER_ASSERT(reporter, result == (int32_t)check);
    553 
    554         // make them <= 2^24, so we don't overflow in fixmul
    555         numer = numer << 8 >> 8;
    556         denom = denom << 8 >> 8;
    557 
    558         result = SkFixedMul(numer, denom);
    559         SkFixed r2 = symmetric_fixmul(numer, denom);
    560         //        SkASSERT(result == r2);
    561 
    562         result = SkFixedMul(numer, numer);
    563         r2 = SkFixedSquare(numer);
    564         REPORTER_ASSERT(reporter, result == r2);
    565 
    566         if (numer >= 0 && denom >= 0) {
    567             SkFixed mean = SkFixedMean(numer, denom);
    568             float prod = SkFixedToFloat(numer) * SkFixedToFloat(denom);
    569             float fm = sk_float_sqrt(sk_float_abs(prod));
    570             SkFixed mean2 = SkFloatToFixed(fm);
    571             int diff = SkAbs32(mean - mean2);
    572             REPORTER_ASSERT(reporter, diff <= 1);
    573         }
    574 
    575         {
    576             SkFixed mod = SkFixedMod(numer, denom);
    577             float n = SkFixedToFloat(numer);
    578             float d = SkFixedToFloat(denom);
    579             float m = sk_float_mod(n, d);
    580             // ensure the same sign
    581             REPORTER_ASSERT(reporter, mod == 0 || (mod < 0) == (m < 0));
    582             int diff = SkAbs32(mod - SkFloatToFixed(m));
    583             REPORTER_ASSERT(reporter, (diff >> 7) == 0);
    584         }
    585     }
    586 #endif
    587 
    588     for (i = 0; i < 10000; i++) {
    589         SkFract x = rand.nextU() >> 1;
    590         double xx = (double)x / SK_Fract1;
    591         SkFract xr = SkFractSqrt(x);
    592         SkFract check = SkFloatToFract(sqrt(xx));
    593         REPORTER_ASSERT(reporter, xr == check ||
    594                                   xr == check-1 ||
    595                                   xr == check+1);
    596 
    597         xr = SkFixedSqrt(x);
    598         xx = (double)x / SK_Fixed1;
    599         check = SkFloatToFixed(sqrt(xx));
    600         REPORTER_ASSERT(reporter, xr == check || xr == check-1);
    601 
    602         xr = SkSqrt32(x);
    603         xx = (double)x;
    604         check = (int32_t)sqrt(xx);
    605         REPORTER_ASSERT(reporter, xr == check || xr == check-1);
    606     }
    607 
    608 #if !defined(SK_SCALAR_IS_FLOAT)
    609     {
    610         SkFixed s, c;
    611         s = SkFixedSinCos(0, &c);
    612         REPORTER_ASSERT(reporter, s == 0);
    613         REPORTER_ASSERT(reporter, c == SK_Fixed1);
    614     }
    615 
    616     int maxDiff = 0;
    617     for (i = 0; i < 1000; i++) {
    618         SkFixed rads = rand.nextS() >> 10;
    619         double frads = SkFixedToFloat(rads);
    620 
    621         SkFixed s, c;
    622         s = SkScalarSinCos(rads, &c);
    623 
    624         double fs = sin(frads);
    625         double fc = cos(frads);
    626 
    627         SkFixed is = SkFloatToFixed(fs);
    628         SkFixed ic = SkFloatToFixed(fc);
    629 
    630         maxDiff = SkMax32(maxDiff, SkAbs32(is - s));
    631         maxDiff = SkMax32(maxDiff, SkAbs32(ic - c));
    632     }
    633     SkDebugf("SinCos: maximum error = %d\n", maxDiff);
    634 #endif
    635 
    636 #ifdef SK_SCALAR_IS_FLOAT
    637     test_blend(reporter);
    638 #endif
    639 
    640     if (false) test_floor(reporter);
    641 
    642     // disable for now
    643     if (false) test_blend31();  // avoid bit rot, suppress warning
    644 
    645     test_muldivround(reporter);
    646     test_clz(reporter);
    647 }
    648 
    649 #include "TestClassDef.h"
    650 DEFINE_TESTCLASS("Math", MathTestClass, TestMath)
    651 
    652 ///////////////////////////////////////////////////////////////////////////////
    653 
    654 #include "SkEndian.h"
    655 
    656 template <typename T> struct PairRec {
    657     T   fYin;
    658     T   fYang;
    659 };
    660 
    661 static void TestEndian(skiatest::Reporter* reporter) {
    662     static const PairRec<uint16_t> g16[] = {
    663         { 0x0,      0x0     },
    664         { 0xFFFF,   0xFFFF  },
    665         { 0x1122,   0x2211  },
    666     };
    667     static const PairRec<uint32_t> g32[] = {
    668         { 0x0,          0x0         },
    669         { 0xFFFFFFFF,   0xFFFFFFFF  },
    670         { 0x11223344,   0x44332211  },
    671     };
    672     static const PairRec<uint64_t> g64[] = {
    673         { 0x0,      0x0                             },
    674         { 0xFFFFFFFFFFFFFFFFULL,  0xFFFFFFFFFFFFFFFFULL  },
    675         { 0x1122334455667788ULL,  0x8877665544332211ULL  },
    676     };
    677 
    678     REPORTER_ASSERT(reporter, 0x1122 == SkTEndianSwap16<0x2211>::value);
    679     REPORTER_ASSERT(reporter, 0x11223344 == SkTEndianSwap32<0x44332211>::value);
    680     REPORTER_ASSERT(reporter, 0x1122334455667788ULL == SkTEndianSwap64<0x8877665544332211ULL>::value);
    681 
    682     for (size_t i = 0; i < SK_ARRAY_COUNT(g16); ++i) {
    683         REPORTER_ASSERT(reporter, g16[i].fYang == SkEndianSwap16(g16[i].fYin));
    684     }
    685     for (size_t i = 0; i < SK_ARRAY_COUNT(g32); ++i) {
    686         REPORTER_ASSERT(reporter, g32[i].fYang == SkEndianSwap32(g32[i].fYin));
    687     }
    688     for (size_t i = 0; i < SK_ARRAY_COUNT(g64); ++i) {
    689         REPORTER_ASSERT(reporter, g64[i].fYang == SkEndianSwap64(g64[i].fYin));
    690     }
    691 }
    692 
    693 DEFINE_TESTCLASS("Endian", EndianTestClass, TestEndian)
    694