1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
7e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.org
8e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.org#include "SkColorPriv.h"
9e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.org#include "SkEndian.h"
108afae61a57f87e4a50578effce6c428031499301tomhudson@google.com#include "SkFloatBits.h"
11c846ede6a08d02522c3b58afc29a3d55150dbf83reed@android.com#include "SkFloatingPoint.h"
124b163ed2c22facbe8891616874ae07ba7827d9c9reed@google.com#include "SkMathPriv.h"
13ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "SkPoint.h"
14ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "SkRandom.h"
158f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "Test.h"
16ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
17c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.comstatic void test_clz(skiatest::Reporter* reporter) {
18c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com    REPORTER_ASSERT(reporter, 32 == SkCLZ(0));
19c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com    REPORTER_ASSERT(reporter, 31 == SkCLZ(1));
20c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com    REPORTER_ASSERT(reporter, 1 == SkCLZ(1 << 30));
217729534da419436ea6127545e9f79b0b47ccffb4reed@google.com    REPORTER_ASSERT(reporter, 0 == SkCLZ(~0U));
22815211307368b82a8df503432221b80ab0a804c3skia.committer@gmail.com
23e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org    SkRandom rand;
24c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com    for (int i = 0; i < 1000; ++i) {
25c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com        uint32_t mask = rand.nextU();
26bc57a29a7a9757064389bcd31bbc36069208756areed@google.com        // need to get some zeros for testing, but in some obscure way so the
27bc57a29a7a9757064389bcd31bbc36069208756areed@google.com        // compiler won't "see" that, and work-around calling the functions.
28bc57a29a7a9757064389bcd31bbc36069208756areed@google.com        mask >>= (mask & 31);
29c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com        int intri = SkCLZ(mask);
30c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com        int porta = SkCLZ_portable(mask);
31c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com        REPORTER_ASSERT(reporter, intri == porta);
32c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com    }
33c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com}
34c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com
35c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com///////////////////////////////////////////////////////////////////////////////
36c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com
37a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.comstatic float sk_fsel(float pred, float result_ge, float result_lt) {
38a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com    return pred >= 0 ? result_ge : result_lt;
39a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com}
40a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com
41a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.comstatic float fast_floor(float x) {
42c20bc25b6e11fb068a9b4aefc1a2e576a98835eareed@google.com//    float big = sk_fsel(x, 0x1.0p+23, -0x1.0p+23);
43c20bc25b6e11fb068a9b4aefc1a2e576a98835eareed@google.com    float big = sk_fsel(x, (float)(1 << 23), -(float)(1 << 23));
4400bf06a142e49f2d6f398127d7e3cf747559a461robertphillips@google.com    return (float)(x + big) - big;
45a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com}
46a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com
47a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.comstatic float std_floor(float x) {
48a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com    return sk_float_floor(x);
49a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com}
50a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com
51a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.comstatic void test_floor_value(skiatest::Reporter* reporter, float value) {
52a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com    float fast = fast_floor(value);
53a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com    float std = std_floor(value);
54a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com    REPORTER_ASSERT(reporter, std == fast);
55a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com//    SkDebugf("value[%1.9f] std[%g] fast[%g] equal[%d]\n",
56a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com//             value, std, fast, std == fast);
57a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com}
58a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com
59a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.comstatic void test_floor(skiatest::Reporter* reporter) {
60a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com    static const float gVals[] = {
61a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com        0, 1, 1.1f, 1.01f, 1.001f, 1.0001f, 1.00001f, 1.000001f, 1.0000001f
62a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com    };
63d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
64a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gVals); ++i) {
65a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com        test_floor_value(reporter, gVals[i]);
66a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com//        test_floor_value(reporter, -gVals[i]);
67a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com    }
68a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com}
69a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com
70a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com///////////////////////////////////////////////////////////////////////////////
71a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com
72ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com// test that SkMul16ShiftRound and SkMulDiv255Round return the same result
73ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.comstatic void test_muldivround(skiatest::Reporter* reporter) {
74ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com#if 0
75ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com    // this "complete" test is too slow, so we test a random sampling of it
76ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com
77ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com    for (int a = 0; a <= 32767; ++a) {
78ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com        for (int b = 0; b <= 32767; ++b) {
79ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com            unsigned prod0 = SkMul16ShiftRound(a, b, 8);
80ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com            unsigned prod1 = SkMulDiv255Round(a, b);
81ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com            SkASSERT(prod0 == prod1);
82ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com        }
83ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com    }
84ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com#endif
85ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com
86e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org    SkRandom rand;
87ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com    for (int i = 0; i < 10000; ++i) {
88ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com        unsigned a = rand.nextU() & 0x7FFF;
89ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com        unsigned b = rand.nextU() & 0x7FFF;
90ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com
91ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com        unsigned prod0 = SkMul16ShiftRound(a, b, 8);
92ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com        unsigned prod1 = SkMulDiv255Round(a, b);
93ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com
94ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com        REPORTER_ASSERT(reporter, prod0 == prod1);
95ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com    }
96ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com}
97ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com
980abb499dafb2550ad81afe11ffede5cab4904575reed@google.comstatic float float_blend(int src, int dst, float unit) {
990abb499dafb2550ad81afe11ffede5cab4904575reed@google.com    return dst + (src - dst) * unit;
100772813afa62706bd97024430b4505afe4258687areed@google.com}
101772813afa62706bd97024430b4505afe4258687areed@google.com
1028d7e39c835dee9efb8a92285955044408bc87721reed@google.comstatic int blend31(int src, int dst, int a31) {
1038d7e39c835dee9efb8a92285955044408bc87721reed@google.com    return dst + ((src - dst) * a31 * 2114 >> 16);
1048d7e39c835dee9efb8a92285955044408bc87721reed@google.com    //    return dst + ((src - dst) * a31 * 33 >> 10);
1058d7e39c835dee9efb8a92285955044408bc87721reed@google.com}
1068d7e39c835dee9efb8a92285955044408bc87721reed@google.com
1078d7e39c835dee9efb8a92285955044408bc87721reed@google.comstatic int blend31_slow(int src, int dst, int a31) {
1088d7e39c835dee9efb8a92285955044408bc87721reed@google.com    int prod = src * a31 + (31 - a31) * dst + 16;
1098d7e39c835dee9efb8a92285955044408bc87721reed@google.com    prod = (prod + (prod >> 5)) >> 5;
1108d7e39c835dee9efb8a92285955044408bc87721reed@google.com    return prod;
1118d7e39c835dee9efb8a92285955044408bc87721reed@google.com}
1128d7e39c835dee9efb8a92285955044408bc87721reed@google.com
1138d7e39c835dee9efb8a92285955044408bc87721reed@google.comstatic int blend31_round(int src, int dst, int a31) {
1148d7e39c835dee9efb8a92285955044408bc87721reed@google.com    int prod = (src - dst) * a31 + 16;
1158d7e39c835dee9efb8a92285955044408bc87721reed@google.com    prod = (prod + (prod >> 5)) >> 5;
1168d7e39c835dee9efb8a92285955044408bc87721reed@google.com    return dst + prod;
1178d7e39c835dee9efb8a92285955044408bc87721reed@google.com}
1188d7e39c835dee9efb8a92285955044408bc87721reed@google.com
1198d7e39c835dee9efb8a92285955044408bc87721reed@google.comstatic int blend31_old(int src, int dst, int a31) {
1208d7e39c835dee9efb8a92285955044408bc87721reed@google.com    a31 += a31 >> 4;
1218d7e39c835dee9efb8a92285955044408bc87721reed@google.com    return dst + ((src - dst) * a31 >> 5);
1228d7e39c835dee9efb8a92285955044408bc87721reed@google.com}
1238d7e39c835dee9efb8a92285955044408bc87721reed@google.com
12442639cddc33746b351bbf07c540711eefffe191acaryclark@google.com// suppress unused code warning
12542639cddc33746b351bbf07c540711eefffe191acaryclark@google.comstatic int (*blend_functions[])(int, int, int) = {
12642639cddc33746b351bbf07c540711eefffe191acaryclark@google.com    blend31,
12742639cddc33746b351bbf07c540711eefffe191acaryclark@google.com    blend31_slow,
12842639cddc33746b351bbf07c540711eefffe191acaryclark@google.com    blend31_round,
12942639cddc33746b351bbf07c540711eefffe191acaryclark@google.com    blend31_old
13042639cddc33746b351bbf07c540711eefffe191acaryclark@google.com};
13142639cddc33746b351bbf07c540711eefffe191acaryclark@google.com
1328d7e39c835dee9efb8a92285955044408bc87721reed@google.comstatic void test_blend31() {
1338d7e39c835dee9efb8a92285955044408bc87721reed@google.com    int failed = 0;
1348d7e39c835dee9efb8a92285955044408bc87721reed@google.com    int death = 0;
13542639cddc33746b351bbf07c540711eefffe191acaryclark@google.com    if (false) { // avoid bit rot, suppress warning
13642639cddc33746b351bbf07c540711eefffe191acaryclark@google.com        failed = (*blend_functions[0])(0,0,0);
13742639cddc33746b351bbf07c540711eefffe191acaryclark@google.com    }
1388d7e39c835dee9efb8a92285955044408bc87721reed@google.com    for (int src = 0; src <= 255; src++) {
1398d7e39c835dee9efb8a92285955044408bc87721reed@google.com        for (int dst = 0; dst <= 255; dst++) {
1408d7e39c835dee9efb8a92285955044408bc87721reed@google.com            for (int a = 0; a <= 31; a++) {
1418d7e39c835dee9efb8a92285955044408bc87721reed@google.com//                int r0 = blend31(src, dst, a);
1428d7e39c835dee9efb8a92285955044408bc87721reed@google.com//                int r0 = blend31_round(src, dst, a);
1438d7e39c835dee9efb8a92285955044408bc87721reed@google.com//                int r0 = blend31_old(src, dst, a);
1448d7e39c835dee9efb8a92285955044408bc87721reed@google.com                int r0 = blend31_slow(src, dst, a);
1458d7e39c835dee9efb8a92285955044408bc87721reed@google.com
1468d7e39c835dee9efb8a92285955044408bc87721reed@google.com                float f = float_blend(src, dst, a / 31.f);
1478d7e39c835dee9efb8a92285955044408bc87721reed@google.com                int r1 = (int)f;
1484b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org                int r2 = SkScalarRoundToInt(f);
1498d7e39c835dee9efb8a92285955044408bc87721reed@google.com
1508d7e39c835dee9efb8a92285955044408bc87721reed@google.com                if (r0 != r1 && r0 != r2) {
151fab44db294846ff05d837b9cf0bf97a073891da7bungeman@google.com                    SkDebugf("src:%d dst:%d a:%d result:%d float:%g\n",
152fab44db294846ff05d837b9cf0bf97a073891da7bungeman@google.com                                  src,   dst, a,        r0,      f);
1538d7e39c835dee9efb8a92285955044408bc87721reed@google.com                    failed += 1;
1548d7e39c835dee9efb8a92285955044408bc87721reed@google.com                }
1558d7e39c835dee9efb8a92285955044408bc87721reed@google.com                if (r0 > 255) {
1568d7e39c835dee9efb8a92285955044408bc87721reed@google.com                    death += 1;
157fab44db294846ff05d837b9cf0bf97a073891da7bungeman@google.com                    SkDebugf("death src:%d dst:%d a:%d result:%d float:%g\n",
158fab44db294846ff05d837b9cf0bf97a073891da7bungeman@google.com                                        src,   dst, a,        r0,      f);
1598d7e39c835dee9efb8a92285955044408bc87721reed@google.com                }
1608d7e39c835dee9efb8a92285955044408bc87721reed@google.com            }
1618d7e39c835dee9efb8a92285955044408bc87721reed@google.com        }
1628d7e39c835dee9efb8a92285955044408bc87721reed@google.com    }
1638d7e39c835dee9efb8a92285955044408bc87721reed@google.com    SkDebugf("---- failed %d death %d\n", failed, death);
1648d7e39c835dee9efb8a92285955044408bc87721reed@google.com}
1658d7e39c835dee9efb8a92285955044408bc87721reed@google.com
1660abb499dafb2550ad81afe11ffede5cab4904575reed@google.comstatic void test_blend(skiatest::Reporter* reporter) {
1670abb499dafb2550ad81afe11ffede5cab4904575reed@google.com    for (int src = 0; src <= 255; src++) {
1680abb499dafb2550ad81afe11ffede5cab4904575reed@google.com        for (int dst = 0; dst <= 255; dst++) {
1690abb499dafb2550ad81afe11ffede5cab4904575reed@google.com            for (int a = 0; a <= 255; a++) {
1700abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                int r0 = SkAlphaBlend255(src, dst, a);
1710abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                float f1 = float_blend(src, dst, a / 255.f);
1724b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org                int r1 = SkScalarRoundToInt(f1);
1730abb499dafb2550ad81afe11ffede5cab4904575reed@google.com
1740abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                if (r0 != r1) {
1750abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                    float diff = sk_float_abs(f1 - r1);
1760abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                    diff = sk_float_abs(diff - 0.5f);
1770abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                    if (diff > (1 / 255.f)) {
1780abb499dafb2550ad81afe11ffede5cab4904575reed@google.com#ifdef SK_DEBUG
1790abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                        SkDebugf("src:%d dst:%d a:%d result:%d float:%g\n",
1800abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                                 src, dst, a, r0, f1);
1810abb499dafb2550ad81afe11ffede5cab4904575reed@google.com#endif
1820abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                        REPORTER_ASSERT(reporter, false);
1830abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                    }
1840abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                }
185772813afa62706bd97024430b4505afe4258687areed@google.com            }
186772813afa62706bd97024430b4505afe4258687areed@google.com        }
187772813afa62706bd97024430b4505afe4258687areed@google.com    }
188772813afa62706bd97024430b4505afe4258687areed@google.com}
189772813afa62706bd97024430b4505afe4258687areed@google.com
190ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void check_length(skiatest::Reporter* reporter,
191ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com                         const SkPoint& p, SkScalar targetLen) {
192ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    float x = SkScalarToFloat(p.fX);
193ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    float y = SkScalarToFloat(p.fY);
194ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    float len = sk_float_sqrt(x*x + y*y);
19580e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
196ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    len /= SkScalarToFloat(targetLen);
19780e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
198ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    REPORTER_ASSERT(reporter, len > 0.999f && len < 1.001f);
199ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
200ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
201e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.orgstatic float nextFloat(SkRandom& rand) {
202ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkFloatIntUnion data;
203ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    data.fSignBitInt = rand.nextU();
204ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    return data.fFloat;
205ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
206ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
207ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com/*  returns true if a == b as resulting from (int)x. Since it is undefined
208ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com what to do if the float exceeds 2^32-1, we check for that explicitly.
209ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com */
210ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic bool equal_float_native_skia(float x, uint32_t ni, uint32_t si) {
211ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    if (!(x == x)) {    // NAN
212373ebc634573364c27b1ebd35bb537ef1285cba4bsalomon@google.com        return ((int32_t)si) == SK_MaxS32 || ((int32_t)si) == SK_MinS32;
213ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
214ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    // for out of range, C is undefined, but skia always should return NaN32
215ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    if (x > SK_MaxS32) {
216373ebc634573364c27b1ebd35bb537ef1285cba4bsalomon@google.com        return ((int32_t)si) == SK_MaxS32;
217ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
218ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    if (x < -SK_MaxS32) {
219373ebc634573364c27b1ebd35bb537ef1285cba4bsalomon@google.com        return ((int32_t)si) == SK_MinS32;
220ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
221ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    return si == ni;
222ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
223ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
224ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void assert_float_equal(skiatest::Reporter* reporter, const char op[],
225ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com                               float x, uint32_t ni, uint32_t si) {
226ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    if (!equal_float_native_skia(x, ni, si)) {
227a9325fa237dde2654bc841c2bb0a05fc3e57696ahalcanary@google.com        ERRORF(reporter, "%s float %g bits %x native %x skia %x\n",
228a9325fa237dde2654bc841c2bb0a05fc3e57696ahalcanary@google.com               op, x, SkFloat2Bits(x), ni, si);
229ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
230ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
231ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
232ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void test_float_cast(skiatest::Reporter* reporter, float x) {
233ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int ix = (int)x;
234ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int iix = SkFloatToIntCast(x);
235ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    assert_float_equal(reporter, "cast", x, ix, iix);
236ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
237ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
238ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void test_float_floor(skiatest::Reporter* reporter, float x) {
239ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int ix = (int)floor(x);
240ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int iix = SkFloatToIntFloor(x);
241ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    assert_float_equal(reporter, "floor", x, ix, iix);
242ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
243ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
244ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void test_float_round(skiatest::Reporter* reporter, float x) {
245ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    double xx = x + 0.5;    // need intermediate double to avoid temp loss
246ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int ix = (int)floor(xx);
247ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int iix = SkFloatToIntRound(x);
248ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    assert_float_equal(reporter, "round", x, ix, iix);
249ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
250ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
251ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void test_float_ceil(skiatest::Reporter* reporter, float x) {
252ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int ix = (int)ceil(x);
253ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int iix = SkFloatToIntCeil(x);
254ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    assert_float_equal(reporter, "ceil", x, ix, iix);
255ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
256ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
257ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void test_float_conversions(skiatest::Reporter* reporter, float x) {
258ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    test_float_cast(reporter, x);
259ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    test_float_floor(reporter, x);
260ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    test_float_round(reporter, x);
261ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    test_float_ceil(reporter, x);
262ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
263ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
264ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void test_int2float(skiatest::Reporter* reporter, int ival) {
265ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    float x0 = (float)ival;
266ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    float x1 = SkIntToFloatCast(ival);
267ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    float x2 = SkIntToFloatCast_NoOverflowCheck(ival);
268ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    REPORTER_ASSERT(reporter, x0 == x1);
269ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    REPORTER_ASSERT(reporter, x0 == x2);
270ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
271ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
272ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void unittest_fastfloat(skiatest::Reporter* reporter) {
273e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org    SkRandom rand;
274ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    size_t i;
27580e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
276ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    static const float gFloats[] = {
277ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        0.f, 1.f, 0.5f, 0.499999f, 0.5000001f, 1.f/3,
278ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        0.000000001f, 1000000000.f,     // doesn't overflow
279ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        0.0000000001f, 10000000000.f    // does overflow
280ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    };
281ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    for (i = 0; i < SK_ARRAY_COUNT(gFloats); i++) {
282ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        test_float_conversions(reporter, gFloats[i]);
283ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        test_float_conversions(reporter, -gFloats[i]);
284ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
28580e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
286ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    for (int outer = 0; outer < 100; outer++) {
287ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        rand.setSeed(outer);
288ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        for (i = 0; i < 100000; i++) {
289ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            float x = nextFloat(rand);
290ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            test_float_conversions(reporter, x);
291ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        }
29280e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
293ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        test_int2float(reporter, 0);
294ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        test_int2float(reporter, 1);
295ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        test_int2float(reporter, -1);
296ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        for (i = 0; i < 100000; i++) {
297ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            // for now only test ints that are 24bits or less, since we don't
298ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            // round (down) large ints the same as IEEE...
299ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            int ival = rand.nextU() & 0xFFFFFF;
300ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            test_int2float(reporter, ival);
301ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            test_int2float(reporter, -ival);
302ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        }
303ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
304ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
305ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
306077910e20cda41d7981084fbd047a108894bc8dfreed@google.comstatic float make_zero() {
307077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    return sk_float_sin(0);
308077910e20cda41d7981084fbd047a108894bc8dfreed@google.com}
309077910e20cda41d7981084fbd047a108894bc8dfreed@google.com
310077910e20cda41d7981084fbd047a108894bc8dfreed@google.comstatic void unittest_isfinite(skiatest::Reporter* reporter) {
311bf083a9a2077e26b3e572aeafd6640156ad68e3bepoger@google.com    float nan = sk_float_asin(2);
31275589257c6ac7fc55a66502b74b8bc09c0212featomhudson@google.com    float inf = 1.0f / make_zero();
31375589257c6ac7fc55a66502b74b8bc09c0212featomhudson@google.com    float big = 3.40282e+038f;
314077910e20cda41d7981084fbd047a108894bc8dfreed@google.com
315077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    REPORTER_ASSERT(reporter, !SkScalarIsNaN(inf));
316d41344553163085bfcfaf7d5882c6028934f8e3breed@android.com    REPORTER_ASSERT(reporter, !SkScalarIsNaN(-inf));
317d41344553163085bfcfaf7d5882c6028934f8e3breed@android.com    REPORTER_ASSERT(reporter, !SkScalarIsFinite(inf));
318d41344553163085bfcfaf7d5882c6028934f8e3breed@android.com    REPORTER_ASSERT(reporter, !SkScalarIsFinite(-inf));
319d41344553163085bfcfaf7d5882c6028934f8e3breed@android.com
320d41344553163085bfcfaf7d5882c6028934f8e3breed@android.com    REPORTER_ASSERT(reporter,  SkScalarIsNaN(nan));
321077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    REPORTER_ASSERT(reporter, !SkScalarIsNaN(big));
322077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    REPORTER_ASSERT(reporter, !SkScalarIsNaN(-big));
323077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    REPORTER_ASSERT(reporter, !SkScalarIsNaN(0));
324d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
325077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    REPORTER_ASSERT(reporter, !SkScalarIsFinite(nan));
326077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    REPORTER_ASSERT(reporter,  SkScalarIsFinite(big));
327077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    REPORTER_ASSERT(reporter,  SkScalarIsFinite(-big));
328077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    REPORTER_ASSERT(reporter,  SkScalarIsFinite(0));
329077910e20cda41d7981084fbd047a108894bc8dfreed@google.com}
330077910e20cda41d7981084fbd047a108894bc8dfreed@google.com
331ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void test_muldiv255(skiatest::Reporter* reporter) {
332ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    for (int a = 0; a <= 255; a++) {
333ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        for (int b = 0; b <= 255; b++) {
334ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            int ab = a * b;
335ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            float s = ab / 255.0f;
336ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            int round = (int)floorf(s + 0.5f);
337ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            int trunc = (int)floorf(s);
33880e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
339ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            int iround = SkMulDiv255Round(a, b);
340ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            int itrunc = SkMulDiv255Trunc(a, b);
34180e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
342ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            REPORTER_ASSERT(reporter, iround == round);
343ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            REPORTER_ASSERT(reporter, itrunc == trunc);
34480e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
345ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            REPORTER_ASSERT(reporter, itrunc <= iround);
346ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            REPORTER_ASSERT(reporter, iround <= a);
347ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            REPORTER_ASSERT(reporter, iround <= b);
348ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        }
349ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
350ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
351ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
352ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.orgstatic void test_muldiv255ceiling(skiatest::Reporter* reporter) {
353ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org    for (int c = 0; c <= 255; c++) {
354ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org        for (int a = 0; a <= 255; a++) {
355ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org            int product = (c * a + 255);
356ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org            int expected_ceiling = (product + (product >> 8)) >> 8;
357ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org            int webkit_ceiling = (c * a + 254) / 255;
358ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org            REPORTER_ASSERT(reporter, expected_ceiling == webkit_ceiling);
359ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org            int skia_ceiling = SkMulDiv255Ceiling(c, a);
360ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org            REPORTER_ASSERT(reporter, skia_ceiling == webkit_ceiling);
361ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org        }
362ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org    }
363ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org}
364ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org
365f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.comstatic void test_copysign(skiatest::Reporter* reporter) {
366f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com    static const int32_t gTriples[] = {
367f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        // x, y, expected result
368f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        0, 0, 0,
369f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        0, 1, 0,
370f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        0, -1, 0,
371f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        1, 0, 1,
372f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        1, 1, 1,
373f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        1, -1, -1,
374f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        -1, 0, 1,
375f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        -1, 1, 1,
376f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        -1, -1, -1,
377f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com    };
378f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gTriples); i += 3) {
379f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter,
380f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com                        SkCopySign32(gTriples[i], gTriples[i+1]) == gTriples[i+2]);
381f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        float x = (float)gTriples[i];
382f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        float y = (float)gTriples[i+1];
383f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        float expected = (float)gTriples[i+2];
384f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter, sk_float_copysign(x, y) == expected);
385f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com    }
386f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com
387e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org    SkRandom rand;
388f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com    for (int j = 0; j < 1000; j++) {
389f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        int ix = rand.nextS();
390f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter, SkCopySign32(ix, ix) == ix);
391f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter, SkCopySign32(ix, -ix) == -ix);
392f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter, SkCopySign32(-ix, ix) == ix);
393f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter, SkCopySign32(-ix, -ix) == -ix);
394f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com
395f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        SkScalar sx = rand.nextSScalar1();
396f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter, SkScalarCopySign(sx, sx) == sx);
397f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter, SkScalarCopySign(sx, -sx) == -sx);
398f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter, SkScalarCopySign(-sx, sx) == sx);
399f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter, SkScalarCopySign(-sx, -sx) == -sx);
400f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com    }
401f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com}
402f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com
403e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.orgDEF_TEST(Math, reporter) {
404ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int         i;
405e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org    SkRandom    rand;
40680e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
407ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    // these should assert
408ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#if 0
409ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkToS8(128);
410ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkToS8(-129);
411ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkToU8(256);
412ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkToU8(-5);
41380e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
414ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkToS16(32768);
415ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkToS16(-32769);
416ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkToU16(65536);
417ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkToU16(-5);
41880e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
419ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    if (sizeof(size_t) > 4) {
420ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkToS32(4*1024*1024);
421ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkToS32(-4*1024*1024);
422ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkToU32(5*1024*1024);
423ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkToU32(-5);
424ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
425ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#endif
42680e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
427ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    test_muldiv255(reporter);
428ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org    test_muldiv255ceiling(reporter);
429f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com    test_copysign(reporter);
43080e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
431ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    {
432ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkScalar x = SK_ScalarNaN;
433ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, SkScalarIsNaN(x));
434ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
43580e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
436ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    for (i = 0; i < 1000; i++) {
437ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        int value = rand.nextS16();
438ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        int max = rand.nextU16();
43980e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
440ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        int clamp = SkClampMax(value, max);
441ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        int clamp2 = value < 0 ? 0 : (value > max ? max : value);
442ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, clamp == clamp2);
443ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
44480e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
445e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com    for (i = 0; i < 10000; i++) {
446ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkPoint p;
44780e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
44875589257c6ac7fc55a66502b74b8bc09c0212featomhudson@google.com        // These random values are being treated as 32-bit-patterns, not as
44975589257c6ac7fc55a66502b74b8bc09c0212featomhudson@google.com        // ints; calling SkIntToScalar() here produces crashes.
4504debcac8c38cae17a01e697578719c60a068052frobertphillips@google.com        p.setLength((SkScalar) rand.nextS(),
451d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                    (SkScalar) rand.nextS(),
4524debcac8c38cae17a01e697578719c60a068052frobertphillips@google.com                    SK_Scalar1);
453ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        check_length(reporter, p, SK_Scalar1);
4544debcac8c38cae17a01e697578719c60a068052frobertphillips@google.com        p.setLength((SkScalar) (rand.nextS() >> 13),
455d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                    (SkScalar) (rand.nextS() >> 13),
4564debcac8c38cae17a01e697578719c60a068052frobertphillips@google.com                    SK_Scalar1);
457ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        check_length(reporter, p, SK_Scalar1);
458ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
45980e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
460ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    {
461ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkFixed result = SkFixedDiv(100, 100);
462ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, result == SK_Fixed1);
463ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        result = SkFixedDiv(1, SK_Fixed1);
464ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, result == 1);
465ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
46680e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
467ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    unittest_fastfloat(reporter);
468077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    unittest_isfinite(reporter);
46980e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
470e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com    for (i = 0; i < 10000; i++) {
471ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkFixed numer = rand.nextS();
472ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkFixed denom = rand.nextS();
473ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkFixed result = SkFixedDiv(numer, denom);
47401c41a556e0ef0ae2338a1b5ae110a501e1ed0a8reed@google.com        int64_t check = ((int64_t)numer << 16) / denom;
47580e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
476ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        (void)SkCLZ(numer);
477ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        (void)SkCLZ(denom);
47880e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
479ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, result != (SkFixed)SK_NaN32);
480ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        if (check > SK_MaxS32) {
481ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            check = SK_MaxS32;
482ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        } else if (check < -SK_MaxS32) {
483ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            check = SK_MinS32;
484ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        }
485ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, result == (int32_t)check);
486ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
48780e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
4880abb499dafb2550ad81afe11ffede5cab4904575reed@google.com    test_blend(reporter);
4898d7e39c835dee9efb8a92285955044408bc87721reed@google.com
49005af1afd429808913683da75644e48bece12e820humper@google.com    if (false) test_floor(reporter);
491a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com
4928d7e39c835dee9efb8a92285955044408bc87721reed@google.com    // disable for now
49342639cddc33746b351bbf07c540711eefffe191acaryclark@google.com    if (false) test_blend31();  // avoid bit rot, suppress warning
494ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com
495ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com    test_muldivround(reporter);
496c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com    test_clz(reporter);
497ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
498ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
499c9f81661c17b6315df45440541ac799c8034f849reed@google.comtemplate <typename T> struct PairRec {
500c9f81661c17b6315df45440541ac799c8034f849reed@google.com    T   fYin;
501c9f81661c17b6315df45440541ac799c8034f849reed@google.com    T   fYang;
502c9f81661c17b6315df45440541ac799c8034f849reed@google.com};
503c9f81661c17b6315df45440541ac799c8034f849reed@google.com
504e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.orgDEF_TEST(TestEndian, reporter) {
505c9f81661c17b6315df45440541ac799c8034f849reed@google.com    static const PairRec<uint16_t> g16[] = {
506c9f81661c17b6315df45440541ac799c8034f849reed@google.com        { 0x0,      0x0     },
507c9f81661c17b6315df45440541ac799c8034f849reed@google.com        { 0xFFFF,   0xFFFF  },
508c9f81661c17b6315df45440541ac799c8034f849reed@google.com        { 0x1122,   0x2211  },
509c9f81661c17b6315df45440541ac799c8034f849reed@google.com    };
510c9f81661c17b6315df45440541ac799c8034f849reed@google.com    static const PairRec<uint32_t> g32[] = {
511c9f81661c17b6315df45440541ac799c8034f849reed@google.com        { 0x0,          0x0         },
512c9f81661c17b6315df45440541ac799c8034f849reed@google.com        { 0xFFFFFFFF,   0xFFFFFFFF  },
513c9f81661c17b6315df45440541ac799c8034f849reed@google.com        { 0x11223344,   0x44332211  },
514c9f81661c17b6315df45440541ac799c8034f849reed@google.com    };
515c9f81661c17b6315df45440541ac799c8034f849reed@google.com    static const PairRec<uint64_t> g64[] = {
516c9f81661c17b6315df45440541ac799c8034f849reed@google.com        { 0x0,      0x0                             },
517c9f81661c17b6315df45440541ac799c8034f849reed@google.com        { 0xFFFFFFFFFFFFFFFFULL,  0xFFFFFFFFFFFFFFFFULL  },
518c9f81661c17b6315df45440541ac799c8034f849reed@google.com        { 0x1122334455667788ULL,  0x8877665544332211ULL  },
519c9f81661c17b6315df45440541ac799c8034f849reed@google.com    };
520c9f81661c17b6315df45440541ac799c8034f849reed@google.com
521c9f81661c17b6315df45440541ac799c8034f849reed@google.com    REPORTER_ASSERT(reporter, 0x1122 == SkTEndianSwap16<0x2211>::value);
522c9f81661c17b6315df45440541ac799c8034f849reed@google.com    REPORTER_ASSERT(reporter, 0x11223344 == SkTEndianSwap32<0x44332211>::value);
523c9f81661c17b6315df45440541ac799c8034f849reed@google.com    REPORTER_ASSERT(reporter, 0x1122334455667788ULL == SkTEndianSwap64<0x8877665544332211ULL>::value);
524c9f81661c17b6315df45440541ac799c8034f849reed@google.com
525c9f81661c17b6315df45440541ac799c8034f849reed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(g16); ++i) {
526c9f81661c17b6315df45440541ac799c8034f849reed@google.com        REPORTER_ASSERT(reporter, g16[i].fYang == SkEndianSwap16(g16[i].fYin));
527c9f81661c17b6315df45440541ac799c8034f849reed@google.com    }
528c9f81661c17b6315df45440541ac799c8034f849reed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(g32); ++i) {
529c9f81661c17b6315df45440541ac799c8034f849reed@google.com        REPORTER_ASSERT(reporter, g32[i].fYang == SkEndianSwap32(g32[i].fYin));
530c9f81661c17b6315df45440541ac799c8034f849reed@google.com    }
531c9f81661c17b6315df45440541ac799c8034f849reed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(g64); ++i) {
532c9f81661c17b6315df45440541ac799c8034f849reed@google.com        REPORTER_ASSERT(reporter, g64[i].fYang == SkEndianSwap64(g64[i].fYin));
533c9f81661c17b6315df45440541ac799c8034f849reed@google.com    }
534c9f81661c17b6315df45440541ac799c8034f849reed@google.com}
535c9f81661c17b6315df45440541ac799c8034f849reed@google.com
5362c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgtemplate <typename T>
5372c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgstatic void test_divmod(skiatest::Reporter* r) {
5382c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    const struct {
5392c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        T numer;
5402c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        T denom;
5412c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    } kEdgeCases[] = {
5422c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        {(T)17, (T)17},
5432c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        {(T)17, (T)4},
5442c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        {(T)0,  (T)17},
5452c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        // For unsigned T these negatives are just some large numbers.  Doesn't hurt to test them.
5462c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        {(T)-17, (T)-17},
5472c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        {(T)-17, (T)4},
5482c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        {(T)17,  (T)-4},
5492c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        {(T)-17, (T)-4},
5502c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    };
5512c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
5522c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    for (size_t i = 0; i < SK_ARRAY_COUNT(kEdgeCases); i++) {
5532c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        const T numer = kEdgeCases[i].numer;
5542c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        const T denom = kEdgeCases[i].denom;
5552c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        T div, mod;
5562c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        SkTDivMod(numer, denom, &div, &mod);
5572c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        REPORTER_ASSERT(r, numer/denom == div);
5582c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        REPORTER_ASSERT(r, numer%denom == mod);
5592c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    }
5602c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
5612c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    SkRandom rand;
5622c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    for (size_t i = 0; i < 10000; i++) {
5632c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        const T numer = (T)rand.nextS();
5642c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        T denom = 0;
5652c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        while (0 == denom) {
5662c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org            denom = (T)rand.nextS();
5672c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        }
5682c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        T div, mod;
5692c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        SkTDivMod(numer, denom, &div, &mod);
5702c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        REPORTER_ASSERT(r, numer/denom == div);
5712c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        REPORTER_ASSERT(r, numer%denom == mod);
5722c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    }
5732c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org}
5742c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
5752c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgDEF_TEST(divmod_u8, r) {
5762c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    test_divmod<uint8_t>(r);
5772c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org}
5782c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
5792c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgDEF_TEST(divmod_u16, r) {
5802c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    test_divmod<uint16_t>(r);
5812c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org}
5822c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
5832c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgDEF_TEST(divmod_u32, r) {
5842c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    test_divmod<uint32_t>(r);
5852c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org}
5862c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
5872c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgDEF_TEST(divmod_u64, r) {
5882c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    test_divmod<uint64_t>(r);
5892c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org}
5902c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
5912c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgDEF_TEST(divmod_s8, r) {
5922c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    test_divmod<int8_t>(r);
5932c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org}
5942c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
5952c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgDEF_TEST(divmod_s16, r) {
5962c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    test_divmod<int16_t>(r);
5972c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org}
5982c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
5992c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgDEF_TEST(divmod_s32, r) {
6002c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    test_divmod<int32_t>(r);
6012c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org}
6022c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
6032c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgDEF_TEST(divmod_s64, r) {
6042c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    test_divmod<int64_t>(r);
6052c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org}
606