MathTest.cpp revision e4fafb146e85cdfcf9d5418597b6818aa0754ada
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
8ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "Test.h"
9e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.org#include "TestClassDef.h"
10e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.org#include "SkColorPriv.h"
11e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.org#include "SkEndian.h"
128afae61a57f87e4a50578effce6c428031499301tomhudson@google.com#include "SkFloatBits.h"
13c846ede6a08d02522c3b58afc29a3d55150dbf83reed@android.com#include "SkFloatingPoint.h"
144b163ed2c22facbe8891616874ae07ba7827d9c9reed@google.com#include "SkMathPriv.h"
15ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "SkPoint.h"
16ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "SkRandom.h"
17ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
18c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.comstatic void test_clz(skiatest::Reporter* reporter) {
19c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com    REPORTER_ASSERT(reporter, 32 == SkCLZ(0));
20c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com    REPORTER_ASSERT(reporter, 31 == SkCLZ(1));
21c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com    REPORTER_ASSERT(reporter, 1 == SkCLZ(1 << 30));
227729534da419436ea6127545e9f79b0b47ccffb4reed@google.com    REPORTER_ASSERT(reporter, 0 == SkCLZ(~0U));
23815211307368b82a8df503432221b80ab0a804c3skia.committer@gmail.com
24e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org    SkRandom rand;
25c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com    for (int i = 0; i < 1000; ++i) {
26c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com        uint32_t mask = rand.nextU();
27bc57a29a7a9757064389bcd31bbc36069208756areed@google.com        // need to get some zeros for testing, but in some obscure way so the
28bc57a29a7a9757064389bcd31bbc36069208756areed@google.com        // compiler won't "see" that, and work-around calling the functions.
29bc57a29a7a9757064389bcd31bbc36069208756areed@google.com        mask >>= (mask & 31);
30c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com        int intri = SkCLZ(mask);
31c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com        int porta = SkCLZ_portable(mask);
32c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com        REPORTER_ASSERT(reporter, intri == porta);
33c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com    }
34c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com}
35c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com
36c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com///////////////////////////////////////////////////////////////////////////////
37c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com
38a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.comstatic float sk_fsel(float pred, float result_ge, float result_lt) {
39a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com    return pred >= 0 ? result_ge : result_lt;
40a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com}
41a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com
42a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.comstatic float fast_floor(float x) {
43c20bc25b6e11fb068a9b4aefc1a2e576a98835eareed@google.com//    float big = sk_fsel(x, 0x1.0p+23, -0x1.0p+23);
44c20bc25b6e11fb068a9b4aefc1a2e576a98835eareed@google.com    float big = sk_fsel(x, (float)(1 << 23), -(float)(1 << 23));
4500bf06a142e49f2d6f398127d7e3cf747559a461robertphillips@google.com    return (float)(x + big) - big;
46a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com}
47a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com
48a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.comstatic float std_floor(float x) {
49a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com    return sk_float_floor(x);
50a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com}
51a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com
52a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.comstatic void test_floor_value(skiatest::Reporter* reporter, float value) {
53a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com    float fast = fast_floor(value);
54a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com    float std = std_floor(value);
55a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com    REPORTER_ASSERT(reporter, std == fast);
56a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com//    SkDebugf("value[%1.9f] std[%g] fast[%g] equal[%d]\n",
57a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com//             value, std, fast, std == fast);
58a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com}
59a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com
60a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.comstatic void test_floor(skiatest::Reporter* reporter) {
61a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com    static const float gVals[] = {
62a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com        0, 1, 1.1f, 1.01f, 1.001f, 1.0001f, 1.00001f, 1.000001f, 1.0000001f
63a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com    };
64d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
65a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gVals); ++i) {
66a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com        test_floor_value(reporter, gVals[i]);
67a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com//        test_floor_value(reporter, -gVals[i]);
68a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com    }
69a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com}
70a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com
71a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com///////////////////////////////////////////////////////////////////////////////
72a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com
73ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com// test that SkMul16ShiftRound and SkMulDiv255Round return the same result
74ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.comstatic void test_muldivround(skiatest::Reporter* reporter) {
75ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com#if 0
76ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com    // this "complete" test is too slow, so we test a random sampling of it
77ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com
78ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com    for (int a = 0; a <= 32767; ++a) {
79ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com        for (int b = 0; b <= 32767; ++b) {
80ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com            unsigned prod0 = SkMul16ShiftRound(a, b, 8);
81ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com            unsigned prod1 = SkMulDiv255Round(a, b);
82ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com            SkASSERT(prod0 == prod1);
83ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com        }
84ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com    }
85ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com#endif
86ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com
87e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org    SkRandom rand;
88ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com    for (int i = 0; i < 10000; ++i) {
89ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com        unsigned a = rand.nextU() & 0x7FFF;
90ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com        unsigned b = rand.nextU() & 0x7FFF;
91ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com
92ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com        unsigned prod0 = SkMul16ShiftRound(a, b, 8);
93ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com        unsigned prod1 = SkMulDiv255Round(a, b);
94ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com
95ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com        REPORTER_ASSERT(reporter, prod0 == prod1);
96ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com    }
97ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com}
98ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com
990abb499dafb2550ad81afe11ffede5cab4904575reed@google.comstatic float float_blend(int src, int dst, float unit) {
1000abb499dafb2550ad81afe11ffede5cab4904575reed@google.com    return dst + (src - dst) * unit;
101772813afa62706bd97024430b4505afe4258687areed@google.com}
102772813afa62706bd97024430b4505afe4258687areed@google.com
1038d7e39c835dee9efb8a92285955044408bc87721reed@google.comstatic int blend31(int src, int dst, int a31) {
1048d7e39c835dee9efb8a92285955044408bc87721reed@google.com    return dst + ((src - dst) * a31 * 2114 >> 16);
1058d7e39c835dee9efb8a92285955044408bc87721reed@google.com    //    return dst + ((src - dst) * a31 * 33 >> 10);
1068d7e39c835dee9efb8a92285955044408bc87721reed@google.com}
1078d7e39c835dee9efb8a92285955044408bc87721reed@google.com
1088d7e39c835dee9efb8a92285955044408bc87721reed@google.comstatic int blend31_slow(int src, int dst, int a31) {
1098d7e39c835dee9efb8a92285955044408bc87721reed@google.com    int prod = src * a31 + (31 - a31) * dst + 16;
1108d7e39c835dee9efb8a92285955044408bc87721reed@google.com    prod = (prod + (prod >> 5)) >> 5;
1118d7e39c835dee9efb8a92285955044408bc87721reed@google.com    return prod;
1128d7e39c835dee9efb8a92285955044408bc87721reed@google.com}
1138d7e39c835dee9efb8a92285955044408bc87721reed@google.com
1148d7e39c835dee9efb8a92285955044408bc87721reed@google.comstatic int blend31_round(int src, int dst, int a31) {
1158d7e39c835dee9efb8a92285955044408bc87721reed@google.com    int prod = (src - dst) * a31 + 16;
1168d7e39c835dee9efb8a92285955044408bc87721reed@google.com    prod = (prod + (prod >> 5)) >> 5;
1178d7e39c835dee9efb8a92285955044408bc87721reed@google.com    return dst + prod;
1188d7e39c835dee9efb8a92285955044408bc87721reed@google.com}
1198d7e39c835dee9efb8a92285955044408bc87721reed@google.com
1208d7e39c835dee9efb8a92285955044408bc87721reed@google.comstatic int blend31_old(int src, int dst, int a31) {
1218d7e39c835dee9efb8a92285955044408bc87721reed@google.com    a31 += a31 >> 4;
1228d7e39c835dee9efb8a92285955044408bc87721reed@google.com    return dst + ((src - dst) * a31 >> 5);
1238d7e39c835dee9efb8a92285955044408bc87721reed@google.com}
1248d7e39c835dee9efb8a92285955044408bc87721reed@google.com
12542639cddc33746b351bbf07c540711eefffe191acaryclark@google.com// suppress unused code warning
12642639cddc33746b351bbf07c540711eefffe191acaryclark@google.comstatic int (*blend_functions[])(int, int, int) = {
12742639cddc33746b351bbf07c540711eefffe191acaryclark@google.com    blend31,
12842639cddc33746b351bbf07c540711eefffe191acaryclark@google.com    blend31_slow,
12942639cddc33746b351bbf07c540711eefffe191acaryclark@google.com    blend31_round,
13042639cddc33746b351bbf07c540711eefffe191acaryclark@google.com    blend31_old
13142639cddc33746b351bbf07c540711eefffe191acaryclark@google.com};
13242639cddc33746b351bbf07c540711eefffe191acaryclark@google.com
1338d7e39c835dee9efb8a92285955044408bc87721reed@google.comstatic void test_blend31() {
1348d7e39c835dee9efb8a92285955044408bc87721reed@google.com    int failed = 0;
1358d7e39c835dee9efb8a92285955044408bc87721reed@google.com    int death = 0;
13642639cddc33746b351bbf07c540711eefffe191acaryclark@google.com    if (false) { // avoid bit rot, suppress warning
13742639cddc33746b351bbf07c540711eefffe191acaryclark@google.com        failed = (*blend_functions[0])(0,0,0);
13842639cddc33746b351bbf07c540711eefffe191acaryclark@google.com    }
1398d7e39c835dee9efb8a92285955044408bc87721reed@google.com    for (int src = 0; src <= 255; src++) {
1408d7e39c835dee9efb8a92285955044408bc87721reed@google.com        for (int dst = 0; dst <= 255; dst++) {
1418d7e39c835dee9efb8a92285955044408bc87721reed@google.com            for (int a = 0; a <= 31; a++) {
1428d7e39c835dee9efb8a92285955044408bc87721reed@google.com//                int r0 = blend31(src, dst, a);
1438d7e39c835dee9efb8a92285955044408bc87721reed@google.com//                int r0 = blend31_round(src, dst, a);
1448d7e39c835dee9efb8a92285955044408bc87721reed@google.com//                int r0 = blend31_old(src, dst, a);
1458d7e39c835dee9efb8a92285955044408bc87721reed@google.com                int r0 = blend31_slow(src, dst, a);
1468d7e39c835dee9efb8a92285955044408bc87721reed@google.com
1478d7e39c835dee9efb8a92285955044408bc87721reed@google.com                float f = float_blend(src, dst, a / 31.f);
1488d7e39c835dee9efb8a92285955044408bc87721reed@google.com                int r1 = (int)f;
1494b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org                int r2 = SkScalarRoundToInt(f);
1508d7e39c835dee9efb8a92285955044408bc87721reed@google.com
1518d7e39c835dee9efb8a92285955044408bc87721reed@google.com                if (r0 != r1 && r0 != r2) {
152fab44db294846ff05d837b9cf0bf97a073891da7bungeman@google.com                    SkDebugf("src:%d dst:%d a:%d result:%d float:%g\n",
153fab44db294846ff05d837b9cf0bf97a073891da7bungeman@google.com                                  src,   dst, a,        r0,      f);
1548d7e39c835dee9efb8a92285955044408bc87721reed@google.com                    failed += 1;
1558d7e39c835dee9efb8a92285955044408bc87721reed@google.com                }
1568d7e39c835dee9efb8a92285955044408bc87721reed@google.com                if (r0 > 255) {
1578d7e39c835dee9efb8a92285955044408bc87721reed@google.com                    death += 1;
158fab44db294846ff05d837b9cf0bf97a073891da7bungeman@google.com                    SkDebugf("death src:%d dst:%d a:%d result:%d float:%g\n",
159fab44db294846ff05d837b9cf0bf97a073891da7bungeman@google.com                                        src,   dst, a,        r0,      f);
1608d7e39c835dee9efb8a92285955044408bc87721reed@google.com                }
1618d7e39c835dee9efb8a92285955044408bc87721reed@google.com            }
1628d7e39c835dee9efb8a92285955044408bc87721reed@google.com        }
1638d7e39c835dee9efb8a92285955044408bc87721reed@google.com    }
1648d7e39c835dee9efb8a92285955044408bc87721reed@google.com    SkDebugf("---- failed %d death %d\n", failed, death);
1658d7e39c835dee9efb8a92285955044408bc87721reed@google.com}
1668d7e39c835dee9efb8a92285955044408bc87721reed@google.com
1670abb499dafb2550ad81afe11ffede5cab4904575reed@google.comstatic void test_blend(skiatest::Reporter* reporter) {
1680abb499dafb2550ad81afe11ffede5cab4904575reed@google.com    for (int src = 0; src <= 255; src++) {
1690abb499dafb2550ad81afe11ffede5cab4904575reed@google.com        for (int dst = 0; dst <= 255; dst++) {
1700abb499dafb2550ad81afe11ffede5cab4904575reed@google.com            for (int a = 0; a <= 255; a++) {
1710abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                int r0 = SkAlphaBlend255(src, dst, a);
1720abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                float f1 = float_blend(src, dst, a / 255.f);
1734b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org                int r1 = SkScalarRoundToInt(f1);
1740abb499dafb2550ad81afe11ffede5cab4904575reed@google.com
1750abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                if (r0 != r1) {
1760abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                    float diff = sk_float_abs(f1 - r1);
1770abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                    diff = sk_float_abs(diff - 0.5f);
1780abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                    if (diff > (1 / 255.f)) {
1790abb499dafb2550ad81afe11ffede5cab4904575reed@google.com#ifdef SK_DEBUG
1800abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                        SkDebugf("src:%d dst:%d a:%d result:%d float:%g\n",
1810abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                                 src, dst, a, r0, f1);
1820abb499dafb2550ad81afe11ffede5cab4904575reed@google.com#endif
1830abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                        REPORTER_ASSERT(reporter, false);
1840abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                    }
1850abb499dafb2550ad81afe11ffede5cab4904575reed@google.com                }
186772813afa62706bd97024430b4505afe4258687areed@google.com            }
187772813afa62706bd97024430b4505afe4258687areed@google.com        }
188772813afa62706bd97024430b4505afe4258687areed@google.com    }
189772813afa62706bd97024430b4505afe4258687areed@google.com}
190772813afa62706bd97024430b4505afe4258687areed@google.com
1910e6e8cc627242cc7e301401cfe112ba98a008101robertphillips@google.com#if defined(SkLONGLONG)
192ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic int symmetric_fixmul(int a, int b) {
193ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int sa = SkExtractSign(a);
194ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int sb = SkExtractSign(b);
19580e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
196ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    a = SkApplySign(a, sa);
197ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    b = SkApplySign(b, sb);
19880e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
199ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#if 1
2000e6e8cc627242cc7e301401cfe112ba98a008101robertphillips@google.com    int c = (int)(((SkLONGLONG)a * b) >> 16);
20180e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
202ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    return SkApplySign(c, sa ^ sb);
203ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#else
2040e6e8cc627242cc7e301401cfe112ba98a008101robertphillips@google.com    SkLONGLONG ab = (SkLONGLONG)a * b;
205ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    if (sa ^ sb) {
206ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        ab = -ab;
207ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
208ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    return ab >> 16;
209ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#endif
210ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
2110e6e8cc627242cc7e301401cfe112ba98a008101robertphillips@google.com#endif
212ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
213ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void check_length(skiatest::Reporter* reporter,
214ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com                         const SkPoint& p, SkScalar targetLen) {
215ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    float x = SkScalarToFloat(p.fX);
216ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    float y = SkScalarToFloat(p.fY);
217ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    float len = sk_float_sqrt(x*x + y*y);
21880e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
219ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    len /= SkScalarToFloat(targetLen);
22080e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
221ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    REPORTER_ASSERT(reporter, len > 0.999f && len < 1.001f);
222ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
223ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
224e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.orgstatic float nextFloat(SkRandom& rand) {
225ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkFloatIntUnion data;
226ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    data.fSignBitInt = rand.nextU();
227ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    return data.fFloat;
228ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
229ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
230ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com/*  returns true if a == b as resulting from (int)x. Since it is undefined
231ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com what to do if the float exceeds 2^32-1, we check for that explicitly.
232ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com */
233ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic bool equal_float_native_skia(float x, uint32_t ni, uint32_t si) {
234ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    if (!(x == x)) {    // NAN
235373ebc634573364c27b1ebd35bb537ef1285cba4bsalomon@google.com        return ((int32_t)si) == SK_MaxS32 || ((int32_t)si) == SK_MinS32;
236ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
237ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    // for out of range, C is undefined, but skia always should return NaN32
238ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    if (x > SK_MaxS32) {
239373ebc634573364c27b1ebd35bb537ef1285cba4bsalomon@google.com        return ((int32_t)si) == SK_MaxS32;
240ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
241ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    if (x < -SK_MaxS32) {
242373ebc634573364c27b1ebd35bb537ef1285cba4bsalomon@google.com        return ((int32_t)si) == SK_MinS32;
243ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
244ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    return si == ni;
245ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
246ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
247ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void assert_float_equal(skiatest::Reporter* reporter, const char op[],
248ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com                               float x, uint32_t ni, uint32_t si) {
249ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    if (!equal_float_native_skia(x, ni, si)) {
250ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkString desc;
2518afae61a57f87e4a50578effce6c428031499301tomhudson@google.com        uint32_t xi = SkFloat2Bits(x);
2528afae61a57f87e4a50578effce6c428031499301tomhudson@google.com        desc.printf("%s float %g bits %x native %x skia %x\n", op, x, xi, ni, si);
253ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        reporter->reportFailed(desc);
254ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
255ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
256ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
257ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void test_float_cast(skiatest::Reporter* reporter, float x) {
258ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int ix = (int)x;
259ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int iix = SkFloatToIntCast(x);
260ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    assert_float_equal(reporter, "cast", x, ix, iix);
261ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
262ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
263ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void test_float_floor(skiatest::Reporter* reporter, float x) {
264ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int ix = (int)floor(x);
265ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int iix = SkFloatToIntFloor(x);
266ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    assert_float_equal(reporter, "floor", x, ix, iix);
267ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
268ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
269ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void test_float_round(skiatest::Reporter* reporter, float x) {
270ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    double xx = x + 0.5;    // need intermediate double to avoid temp loss
271ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int ix = (int)floor(xx);
272ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int iix = SkFloatToIntRound(x);
273ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    assert_float_equal(reporter, "round", x, ix, iix);
274ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
275ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
276ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void test_float_ceil(skiatest::Reporter* reporter, float x) {
277ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int ix = (int)ceil(x);
278ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int iix = SkFloatToIntCeil(x);
279ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    assert_float_equal(reporter, "ceil", x, ix, iix);
280ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
281ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
282ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void test_float_conversions(skiatest::Reporter* reporter, float x) {
283ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    test_float_cast(reporter, x);
284ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    test_float_floor(reporter, x);
285ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    test_float_round(reporter, x);
286ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    test_float_ceil(reporter, x);
287ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
288ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
289ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void test_int2float(skiatest::Reporter* reporter, int ival) {
290ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    float x0 = (float)ival;
291ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    float x1 = SkIntToFloatCast(ival);
292ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    float x2 = SkIntToFloatCast_NoOverflowCheck(ival);
293ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    REPORTER_ASSERT(reporter, x0 == x1);
294ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    REPORTER_ASSERT(reporter, x0 == x2);
295ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
296ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
297ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void unittest_fastfloat(skiatest::Reporter* reporter) {
298e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org    SkRandom rand;
299ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    size_t i;
30080e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
301ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    static const float gFloats[] = {
302ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        0.f, 1.f, 0.5f, 0.499999f, 0.5000001f, 1.f/3,
303ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        0.000000001f, 1000000000.f,     // doesn't overflow
304ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        0.0000000001f, 10000000000.f    // does overflow
305ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    };
306ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    for (i = 0; i < SK_ARRAY_COUNT(gFloats); i++) {
307ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        test_float_conversions(reporter, gFloats[i]);
308ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        test_float_conversions(reporter, -gFloats[i]);
309ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
31080e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
311ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    for (int outer = 0; outer < 100; outer++) {
312ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        rand.setSeed(outer);
313ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        for (i = 0; i < 100000; i++) {
314ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            float x = nextFloat(rand);
315ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            test_float_conversions(reporter, x);
316ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        }
31780e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
318ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        test_int2float(reporter, 0);
319ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        test_int2float(reporter, 1);
320ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        test_int2float(reporter, -1);
321ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        for (i = 0; i < 100000; i++) {
322ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            // for now only test ints that are 24bits or less, since we don't
323ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            // round (down) large ints the same as IEEE...
324ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            int ival = rand.nextU() & 0xFFFFFF;
325ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            test_int2float(reporter, ival);
326ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            test_int2float(reporter, -ival);
327ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        }
328ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
329ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
330ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
331d41344553163085bfcfaf7d5882c6028934f8e3breed@android.com#ifdef SK_SCALAR_IS_FLOAT
332077910e20cda41d7981084fbd047a108894bc8dfreed@google.comstatic float make_zero() {
333077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    return sk_float_sin(0);
334077910e20cda41d7981084fbd047a108894bc8dfreed@google.com}
335d41344553163085bfcfaf7d5882c6028934f8e3breed@android.com#endif
336077910e20cda41d7981084fbd047a108894bc8dfreed@google.com
337077910e20cda41d7981084fbd047a108894bc8dfreed@google.comstatic void unittest_isfinite(skiatest::Reporter* reporter) {
338077910e20cda41d7981084fbd047a108894bc8dfreed@google.com#ifdef SK_SCALAR_IS_FLOAT
339bf083a9a2077e26b3e572aeafd6640156ad68e3bepoger@google.com    float nan = sk_float_asin(2);
34075589257c6ac7fc55a66502b74b8bc09c0212featomhudson@google.com    float inf = 1.0f / make_zero();
34175589257c6ac7fc55a66502b74b8bc09c0212featomhudson@google.com    float big = 3.40282e+038f;
342077910e20cda41d7981084fbd047a108894bc8dfreed@google.com
343077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    REPORTER_ASSERT(reporter, !SkScalarIsNaN(inf));
344d41344553163085bfcfaf7d5882c6028934f8e3breed@android.com    REPORTER_ASSERT(reporter, !SkScalarIsNaN(-inf));
345d41344553163085bfcfaf7d5882c6028934f8e3breed@android.com    REPORTER_ASSERT(reporter, !SkScalarIsFinite(inf));
346d41344553163085bfcfaf7d5882c6028934f8e3breed@android.com    REPORTER_ASSERT(reporter, !SkScalarIsFinite(-inf));
347d41344553163085bfcfaf7d5882c6028934f8e3breed@android.com#else
348d41344553163085bfcfaf7d5882c6028934f8e3breed@android.com    SkFixed nan = SK_FixedNaN;
349d41344553163085bfcfaf7d5882c6028934f8e3breed@android.com    SkFixed big = SK_FixedMax;
350d41344553163085bfcfaf7d5882c6028934f8e3breed@android.com#endif
351d41344553163085bfcfaf7d5882c6028934f8e3breed@android.com
352d41344553163085bfcfaf7d5882c6028934f8e3breed@android.com    REPORTER_ASSERT(reporter,  SkScalarIsNaN(nan));
353077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    REPORTER_ASSERT(reporter, !SkScalarIsNaN(big));
354077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    REPORTER_ASSERT(reporter, !SkScalarIsNaN(-big));
355077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    REPORTER_ASSERT(reporter, !SkScalarIsNaN(0));
356d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
357077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    REPORTER_ASSERT(reporter, !SkScalarIsFinite(nan));
358077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    REPORTER_ASSERT(reporter,  SkScalarIsFinite(big));
359077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    REPORTER_ASSERT(reporter,  SkScalarIsFinite(-big));
360077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    REPORTER_ASSERT(reporter,  SkScalarIsFinite(0));
361077910e20cda41d7981084fbd047a108894bc8dfreed@google.com}
362077910e20cda41d7981084fbd047a108894bc8dfreed@google.com
363ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic void test_muldiv255(skiatest::Reporter* reporter) {
364ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    for (int a = 0; a <= 255; a++) {
365ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        for (int b = 0; b <= 255; b++) {
366ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            int ab = a * b;
367ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            float s = ab / 255.0f;
368ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            int round = (int)floorf(s + 0.5f);
369ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            int trunc = (int)floorf(s);
37080e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
371ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            int iround = SkMulDiv255Round(a, b);
372ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            int itrunc = SkMulDiv255Trunc(a, b);
37380e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
374ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            REPORTER_ASSERT(reporter, iround == round);
375ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            REPORTER_ASSERT(reporter, itrunc == trunc);
37680e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
377ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            REPORTER_ASSERT(reporter, itrunc <= iround);
378ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            REPORTER_ASSERT(reporter, iround <= a);
379ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            REPORTER_ASSERT(reporter, iround <= b);
380ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        }
381ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
382ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
383ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
384ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.orgstatic void test_muldiv255ceiling(skiatest::Reporter* reporter) {
385ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org    for (int c = 0; c <= 255; c++) {
386ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org        for (int a = 0; a <= 255; a++) {
387ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org            int product = (c * a + 255);
388ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org            int expected_ceiling = (product + (product >> 8)) >> 8;
389ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org            int webkit_ceiling = (c * a + 254) / 255;
390ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org            REPORTER_ASSERT(reporter, expected_ceiling == webkit_ceiling);
391ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org            int skia_ceiling = SkMulDiv255Ceiling(c, a);
392ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org            REPORTER_ASSERT(reporter, skia_ceiling == webkit_ceiling);
393ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org        }
394ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org    }
395ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org}
396ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org
397f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.comstatic void test_copysign(skiatest::Reporter* reporter) {
398f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com    static const int32_t gTriples[] = {
399f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        // x, y, expected result
400f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        0, 0, 0,
401f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        0, 1, 0,
402f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        0, -1, 0,
403f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        1, 0, 1,
404f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        1, 1, 1,
405f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        1, -1, -1,
406f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        -1, 0, 1,
407f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        -1, 1, 1,
408f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        -1, -1, -1,
409f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com    };
410f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gTriples); i += 3) {
411f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter,
412f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com                        SkCopySign32(gTriples[i], gTriples[i+1]) == gTriples[i+2]);
413f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        float x = (float)gTriples[i];
414f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        float y = (float)gTriples[i+1];
415f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        float expected = (float)gTriples[i+2];
416f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter, sk_float_copysign(x, y) == expected);
417f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com    }
418f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com
419e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org    SkRandom rand;
420f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com    for (int j = 0; j < 1000; j++) {
421f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        int ix = rand.nextS();
422f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter, SkCopySign32(ix, ix) == ix);
423f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter, SkCopySign32(ix, -ix) == -ix);
424f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter, SkCopySign32(-ix, ix) == ix);
425f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter, SkCopySign32(-ix, -ix) == -ix);
426f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com
427f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        SkScalar sx = rand.nextSScalar1();
428f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter, SkScalarCopySign(sx, sx) == sx);
429f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter, SkScalarCopySign(sx, -sx) == -sx);
430f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter, SkScalarCopySign(-sx, sx) == sx);
431f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com        REPORTER_ASSERT(reporter, SkScalarCopySign(-sx, -sx) == -sx);
432f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com    }
433f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com}
434f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com
435e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.orgDEF_TEST(Math, reporter) {
436ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int         i;
437ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int32_t     x;
438e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org    SkRandom    rand;
43980e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
440ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    // these should assert
441ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#if 0
442ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkToS8(128);
443ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkToS8(-129);
444ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkToU8(256);
445ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkToU8(-5);
44680e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
447ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkToS16(32768);
448ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkToS16(-32769);
449ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkToU16(65536);
450ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkToU16(-5);
45180e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
452ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    if (sizeof(size_t) > 4) {
453ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkToS32(4*1024*1024);
454ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkToS32(-4*1024*1024);
455ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkToU32(5*1024*1024);
456ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkToU32(-5);
457ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
458ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#endif
45980e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
460ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    test_muldiv255(reporter);
461ec7a30cc8688923e0ccfff4c8f81c5e577c4c9absenorblanco@chromium.org    test_muldiv255ceiling(reporter);
462f0ad0864af632736819b9f3f34dbba488c73e3afreed@android.com    test_copysign(reporter);
46380e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
464ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    {
465ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkScalar x = SK_ScalarNaN;
466ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, SkScalarIsNaN(x));
467ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
46880e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
469ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    for (i = 1; i <= 10; i++) {
470ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        x = SkCubeRootBits(i*i*i, 11);
471ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, x == i);
472ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
47380e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
474ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    x = SkFixedSqrt(SK_Fixed1);
475ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    REPORTER_ASSERT(reporter, x == SK_Fixed1);
476ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    x = SkFixedSqrt(SK_Fixed1/4);
477ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    REPORTER_ASSERT(reporter, x == SK_Fixed1/2);
478ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    x = SkFixedSqrt(SK_Fixed1*4);
479ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    REPORTER_ASSERT(reporter, x == SK_Fixed1*2);
48080e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
481ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    x = SkFractSqrt(SK_Fract1);
482ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    REPORTER_ASSERT(reporter, x == SK_Fract1);
483ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    x = SkFractSqrt(SK_Fract1/4);
484ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    REPORTER_ASSERT(reporter, x == SK_Fract1/2);
485ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    x = SkFractSqrt(SK_Fract1/16);
486ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    REPORTER_ASSERT(reporter, x == SK_Fract1/4);
48780e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
488ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    for (i = 1; i < 100; i++) {
489ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        x = SkFixedSqrt(SK_Fixed1 * i * i);
490ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, x == SK_Fixed1 * i);
491ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
49280e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
493ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    for (i = 0; i < 1000; i++) {
494ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        int value = rand.nextS16();
495ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        int max = rand.nextU16();
49680e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
497ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        int clamp = SkClampMax(value, max);
498ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        int clamp2 = value < 0 ? 0 : (value > max ? max : value);
499ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, clamp == clamp2);
500ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
50180e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
502e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com    for (i = 0; i < 10000; i++) {
503ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkPoint p;
50480e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
50575589257c6ac7fc55a66502b74b8bc09c0212featomhudson@google.com        // These random values are being treated as 32-bit-patterns, not as
50675589257c6ac7fc55a66502b74b8bc09c0212featomhudson@google.com        // ints; calling SkIntToScalar() here produces crashes.
5074debcac8c38cae17a01e697578719c60a068052frobertphillips@google.com        p.setLength((SkScalar) rand.nextS(),
508d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                    (SkScalar) rand.nextS(),
5094debcac8c38cae17a01e697578719c60a068052frobertphillips@google.com                    SK_Scalar1);
510ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        check_length(reporter, p, SK_Scalar1);
5114debcac8c38cae17a01e697578719c60a068052frobertphillips@google.com        p.setLength((SkScalar) (rand.nextS() >> 13),
512d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                    (SkScalar) (rand.nextS() >> 13),
5134debcac8c38cae17a01e697578719c60a068052frobertphillips@google.com                    SK_Scalar1);
514ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        check_length(reporter, p, SK_Scalar1);
515ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
51680e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
517ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    {
518ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkFixed result = SkFixedDiv(100, 100);
519ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, result == SK_Fixed1);
520ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        result = SkFixedDiv(1, SK_Fixed1);
521ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, result == 1);
522ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
52380e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
524ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    unittest_fastfloat(reporter);
525077910e20cda41d7981084fbd047a108894bc8dfreed@google.com    unittest_isfinite(reporter);
52680e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
5270e6e8cc627242cc7e301401cfe112ba98a008101robertphillips@google.com#ifdef SkLONGLONG
528e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com    for (i = 0; i < 10000; i++) {
529ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkFixed numer = rand.nextS();
530ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkFixed denom = rand.nextS();
531ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkFixed result = SkFixedDiv(numer, denom);
5320e6e8cc627242cc7e301401cfe112ba98a008101robertphillips@google.com        SkLONGLONG check = ((SkLONGLONG)numer << 16) / denom;
53380e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
534ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        (void)SkCLZ(numer);
535ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        (void)SkCLZ(denom);
53680e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
537ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, result != (SkFixed)SK_NaN32);
538ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        if (check > SK_MaxS32) {
539ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            check = SK_MaxS32;
540ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        } else if (check < -SK_MaxS32) {
541ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            check = SK_MinS32;
542ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        }
543ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, result == (int32_t)check);
54480e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
545ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        result = SkFractDiv(numer, denom);
5460e6e8cc627242cc7e301401cfe112ba98a008101robertphillips@google.com        check = ((SkLONGLONG)numer << 30) / denom;
54780e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
548ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, result != (SkFixed)SK_NaN32);
549ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        if (check > SK_MaxS32) {
550ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            check = SK_MaxS32;
551ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        } else if (check < -SK_MaxS32) {
552ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            check = SK_MinS32;
553ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        }
554ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, result == (int32_t)check);
55580e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
556ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        // make them <= 2^24, so we don't overflow in fixmul
557ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        numer = numer << 8 >> 8;
558ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        denom = denom << 8 >> 8;
55980e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
560ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        result = SkFixedMul(numer, denom);
561ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkFixed r2 = symmetric_fixmul(numer, denom);
562ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        //        SkASSERT(result == r2);
56380e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
564ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        result = SkFixedMul(numer, numer);
565ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        r2 = SkFixedSquare(numer);
566ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, result == r2);
56780e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
568ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        if (numer >= 0 && denom >= 0) {
569ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            SkFixed mean = SkFixedMean(numer, denom);
57080e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com            float prod = SkFixedToFloat(numer) * SkFixedToFloat(denom);
57180e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com            float fm = sk_float_sqrt(sk_float_abs(prod));
572ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            SkFixed mean2 = SkFloatToFixed(fm);
573ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            int diff = SkAbs32(mean - mean2);
574ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            REPORTER_ASSERT(reporter, diff <= 1);
575ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        }
57680e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
577ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        {
578ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            SkFixed mod = SkFixedMod(numer, denom);
579ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            float n = SkFixedToFloat(numer);
580ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            float d = SkFixedToFloat(denom);
581ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            float m = sk_float_mod(n, d);
58280e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com            // ensure the same sign
58380e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com            REPORTER_ASSERT(reporter, mod == 0 || (mod < 0) == (m < 0));
584ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            int diff = SkAbs32(mod - SkFloatToFixed(m));
585ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            REPORTER_ASSERT(reporter, (diff >> 7) == 0);
586ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        }
587ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
5880e6e8cc627242cc7e301401cfe112ba98a008101robertphillips@google.com#endif
58980e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
590e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com    for (i = 0; i < 10000; i++) {
591ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkFract x = rand.nextU() >> 1;
592ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        double xx = (double)x / SK_Fract1;
593ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkFract xr = SkFractSqrt(x);
594ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkFract check = SkFloatToFract(sqrt(xx));
59580e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com        REPORTER_ASSERT(reporter, xr == check ||
59680e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com                                  xr == check-1 ||
59780e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com                                  xr == check+1);
59880e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
599ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        xr = SkFixedSqrt(x);
600ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        xx = (double)x / SK_Fixed1;
601ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        check = SkFloatToFixed(sqrt(xx));
602ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, xr == check || xr == check-1);
60380e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
604ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        xr = SkSqrt32(x);
605ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        xx = (double)x;
606ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        check = (int32_t)sqrt(xx);
607ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, xr == check || xr == check-1);
608ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
60980e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
6107886ad3de1aa523d5c71f1fa9f355dfcb2412d1dreed@google.com#if !defined(SK_SCALAR_IS_FLOAT)
611ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    {
612ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkFixed s, c;
613ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        s = SkFixedSinCos(0, &c);
614ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, s == 0);
615ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        REPORTER_ASSERT(reporter, c == SK_Fixed1);
616ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
61780e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
618ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    int maxDiff = 0;
619e72fee513a5f903d6aa17066d2f3b79ac31f05dereed@android.com    for (i = 0; i < 1000; i++) {
620ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkFixed rads = rand.nextS() >> 10;
621ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        double frads = SkFixedToFloat(rads);
62280e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
623ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkFixed s, c;
624ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        s = SkScalarSinCos(rads, &c);
62580e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
626ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        double fs = sin(frads);
627ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        double fc = cos(frads);
62880e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
629ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkFixed is = SkFloatToFixed(fs);
630ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkFixed ic = SkFloatToFixed(fc);
63180e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
632ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        maxDiff = SkMax32(maxDiff, SkAbs32(is - s));
633ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        maxDiff = SkMax32(maxDiff, SkAbs32(ic - c));
634ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
635ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkDebugf("SinCos: maximum error = %d\n", maxDiff);
636ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#endif
637772813afa62706bd97024430b4505afe4258687areed@google.com
6380abb499dafb2550ad81afe11ffede5cab4904575reed@google.com#ifdef SK_SCALAR_IS_FLOAT
6390abb499dafb2550ad81afe11ffede5cab4904575reed@google.com    test_blend(reporter);
6400abb499dafb2550ad81afe11ffede5cab4904575reed@google.com#endif
6418d7e39c835dee9efb8a92285955044408bc87721reed@google.com
64205af1afd429808913683da75644e48bece12e820humper@google.com    if (false) test_floor(reporter);
643a7d7461cf0835fc42ba9b49feab947395ed73423reed@google.com
6448d7e39c835dee9efb8a92285955044408bc87721reed@google.com    // disable for now
64542639cddc33746b351bbf07c540711eefffe191acaryclark@google.com    if (false) test_blend31();  // avoid bit rot, suppress warning
646ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com
647ea774d2a5a049bf89474c0f047ed6a4e521de126reed@google.com    test_muldivround(reporter);
648c21f86fc91ab3f78f6ecc6b8d52a297dd5317f69reed@google.com    test_clz(reporter);
649ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
650ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
651c9f81661c17b6315df45440541ac799c8034f849reed@google.comtemplate <typename T> struct PairRec {
652c9f81661c17b6315df45440541ac799c8034f849reed@google.com    T   fYin;
653c9f81661c17b6315df45440541ac799c8034f849reed@google.com    T   fYang;
654c9f81661c17b6315df45440541ac799c8034f849reed@google.com};
655c9f81661c17b6315df45440541ac799c8034f849reed@google.com
656e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.orgDEF_TEST(TestEndian, reporter) {
657c9f81661c17b6315df45440541ac799c8034f849reed@google.com    static const PairRec<uint16_t> g16[] = {
658c9f81661c17b6315df45440541ac799c8034f849reed@google.com        { 0x0,      0x0     },
659c9f81661c17b6315df45440541ac799c8034f849reed@google.com        { 0xFFFF,   0xFFFF  },
660c9f81661c17b6315df45440541ac799c8034f849reed@google.com        { 0x1122,   0x2211  },
661c9f81661c17b6315df45440541ac799c8034f849reed@google.com    };
662c9f81661c17b6315df45440541ac799c8034f849reed@google.com    static const PairRec<uint32_t> g32[] = {
663c9f81661c17b6315df45440541ac799c8034f849reed@google.com        { 0x0,          0x0         },
664c9f81661c17b6315df45440541ac799c8034f849reed@google.com        { 0xFFFFFFFF,   0xFFFFFFFF  },
665c9f81661c17b6315df45440541ac799c8034f849reed@google.com        { 0x11223344,   0x44332211  },
666c9f81661c17b6315df45440541ac799c8034f849reed@google.com    };
667c9f81661c17b6315df45440541ac799c8034f849reed@google.com    static const PairRec<uint64_t> g64[] = {
668c9f81661c17b6315df45440541ac799c8034f849reed@google.com        { 0x0,      0x0                             },
669c9f81661c17b6315df45440541ac799c8034f849reed@google.com        { 0xFFFFFFFFFFFFFFFFULL,  0xFFFFFFFFFFFFFFFFULL  },
670c9f81661c17b6315df45440541ac799c8034f849reed@google.com        { 0x1122334455667788ULL,  0x8877665544332211ULL  },
671c9f81661c17b6315df45440541ac799c8034f849reed@google.com    };
672c9f81661c17b6315df45440541ac799c8034f849reed@google.com
673c9f81661c17b6315df45440541ac799c8034f849reed@google.com    REPORTER_ASSERT(reporter, 0x1122 == SkTEndianSwap16<0x2211>::value);
674c9f81661c17b6315df45440541ac799c8034f849reed@google.com    REPORTER_ASSERT(reporter, 0x11223344 == SkTEndianSwap32<0x44332211>::value);
675c9f81661c17b6315df45440541ac799c8034f849reed@google.com    REPORTER_ASSERT(reporter, 0x1122334455667788ULL == SkTEndianSwap64<0x8877665544332211ULL>::value);
676c9f81661c17b6315df45440541ac799c8034f849reed@google.com
677c9f81661c17b6315df45440541ac799c8034f849reed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(g16); ++i) {
678c9f81661c17b6315df45440541ac799c8034f849reed@google.com        REPORTER_ASSERT(reporter, g16[i].fYang == SkEndianSwap16(g16[i].fYin));
679c9f81661c17b6315df45440541ac799c8034f849reed@google.com    }
680c9f81661c17b6315df45440541ac799c8034f849reed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(g32); ++i) {
681c9f81661c17b6315df45440541ac799c8034f849reed@google.com        REPORTER_ASSERT(reporter, g32[i].fYang == SkEndianSwap32(g32[i].fYin));
682c9f81661c17b6315df45440541ac799c8034f849reed@google.com    }
683c9f81661c17b6315df45440541ac799c8034f849reed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(g64); ++i) {
684c9f81661c17b6315df45440541ac799c8034f849reed@google.com        REPORTER_ASSERT(reporter, g64[i].fYang == SkEndianSwap64(g64[i].fYin));
685c9f81661c17b6315df45440541ac799c8034f849reed@google.com    }
686c9f81661c17b6315df45440541ac799c8034f849reed@google.com}
687c9f81661c17b6315df45440541ac799c8034f849reed@google.com
6882c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgtemplate <typename T>
6892c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgstatic void test_divmod(skiatest::Reporter* r) {
6902c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    const struct {
6912c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        T numer;
6922c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        T denom;
6932c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    } kEdgeCases[] = {
6942c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        {(T)17, (T)17},
6952c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        {(T)17, (T)4},
6962c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        {(T)0,  (T)17},
6972c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        // For unsigned T these negatives are just some large numbers.  Doesn't hurt to test them.
6982c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        {(T)-17, (T)-17},
6992c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        {(T)-17, (T)4},
7002c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        {(T)17,  (T)-4},
7012c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        {(T)-17, (T)-4},
7022c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    };
7032c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
7042c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    for (size_t i = 0; i < SK_ARRAY_COUNT(kEdgeCases); i++) {
7052c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        const T numer = kEdgeCases[i].numer;
7062c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        const T denom = kEdgeCases[i].denom;
7072c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        T div, mod;
7082c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        SkTDivMod(numer, denom, &div, &mod);
7092c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        REPORTER_ASSERT(r, numer/denom == div);
7102c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        REPORTER_ASSERT(r, numer%denom == mod);
7112c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    }
7122c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
7132c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    SkRandom rand;
7142c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    for (size_t i = 0; i < 10000; i++) {
7152c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        const T numer = (T)rand.nextS();
7162c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        T denom = 0;
7172c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        while (0 == denom) {
7182c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org            denom = (T)rand.nextS();
7192c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        }
7202c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        T div, mod;
7212c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        SkTDivMod(numer, denom, &div, &mod);
7222c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        REPORTER_ASSERT(r, numer/denom == div);
7232c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org        REPORTER_ASSERT(r, numer%denom == mod);
7242c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    }
7252c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org}
7262c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
7272c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgDEF_TEST(divmod_u8, r) {
7282c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    test_divmod<uint8_t>(r);
7292c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org}
7302c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
7312c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgDEF_TEST(divmod_u16, r) {
7322c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    test_divmod<uint16_t>(r);
7332c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org}
7342c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
7352c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgDEF_TEST(divmod_u32, r) {
7362c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    test_divmod<uint32_t>(r);
7372c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org}
7382c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
7392c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgDEF_TEST(divmod_u64, r) {
7402c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    test_divmod<uint64_t>(r);
7412c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org}
7422c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
7432c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgDEF_TEST(divmod_s8, r) {
7442c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    test_divmod<int8_t>(r);
7452c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org}
7462c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
7472c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgDEF_TEST(divmod_s16, r) {
7482c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    test_divmod<int16_t>(r);
7492c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org}
7502c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
7512c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgDEF_TEST(divmod_s32, r) {
7522c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    test_divmod<int32_t>(r);
7532c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org}
7542c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org
7552c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.orgDEF_TEST(divmod_s64, r) {
7562c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org    test_divmod<int64_t>(r);
7572c86fbb0b14a1f674bf56ea5ad6a086cc004a76ecommit-bot@chromium.org}
758