11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 8da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#include "Test.h" 94c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed#include "SkFloatingPoint.h" 101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkMath.h" 11da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#include "SkPoint.h" 12da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#include "SkRandom.h" 131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkColorPriv.h" 14da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic float float_blend(int src, int dst, float unit) { 161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return dst + (src - dst) * unit; 1787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger} 1887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic int blend31(int src, int dst, int a31) { 201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return dst + ((src - dst) * a31 * 2114 >> 16); 211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // return dst + ((src - dst) * a31 * 33 >> 10); 2287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger} 2387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic int blend31_slow(int src, int dst, int a31) { 251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int prod = src * a31 + (31 - a31) * dst + 16; 261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger prod = (prod + (prod >> 5)) >> 5; 271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return prod; 2887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger} 2987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic int blend31_round(int src, int dst, int a31) { 311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int prod = (src - dst) * a31 + 16; 321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger prod = (prod + (prod >> 5)) >> 5; 331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return dst + prod; 341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic int blend31_old(int src, int dst, int a31) { 371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger a31 += a31 >> 4; 381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return dst + ((src - dst) * a31 >> 5); 391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_blend31() { 421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int failed = 0; 431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int death = 0; 441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int src = 0; src <= 255; src++) { 451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int dst = 0; dst <= 255; dst++) { 461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int a = 0; a <= 31; a++) { 471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// int r0 = blend31(src, dst, a); 481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// int r0 = blend31_round(src, dst, a); 491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// int r0 = blend31_old(src, dst, a); 501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int r0 = blend31_slow(src, dst, a); 511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger float f = float_blend(src, dst, a / 31.f); 531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int r1 = (int)f; 541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int r2 = SkScalarRoundToInt(SkFloatToScalar(f)); 551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (r0 != r1 && r0 != r2) { 571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger printf("src:%d dst:%d a:%d result:%d float:%g\n", 581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src, dst, a, r0, f); 591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger failed += 1; 601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (r0 > 255) { 621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger death += 1; 631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger printf("death src:%d dst:%d a:%d result:%d float:%g\n", 641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src, dst, a, r0, f); 651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } 6787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } 6887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } 691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("---- failed %d death %d\n", failed, death); 7087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger} 711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_blend(skiatest::Reporter* reporter) { 731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int src = 0; src <= 255; src++) { 741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int dst = 0; dst <= 255; dst++) { 751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int a = 0; a <= 255; a++) { 761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int r0 = SkAlphaBlend255(src, dst, a); 771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger float f1 = float_blend(src, dst, a / 255.f); 781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int r1 = SkScalarRoundToInt(SkFloatToScalar(f1)); 791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (r0 != r1) { 811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger float diff = sk_float_abs(f1 - r1); 821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger diff = sk_float_abs(diff - 0.5f); 831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (diff > (1 / 255.f)) { 841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_DEBUG 851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("src:%d dst:%d a:%d result:%d float:%g\n", 861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src, dst, a, r0, f1); 8787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger REPORTER_ASSERT(reporter, false); 891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 9587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 96da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#if defined(SkLONGLONG) 97da3b8b285a5e3e6f344461d67e3370b27701756dMike Reedstatic int symmetric_fixmul(int a, int b) { 98da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int sa = SkExtractSign(a); 99da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int sb = SkExtractSign(b); 100da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 101da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed a = SkApplySign(a, sa); 102da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed b = SkApplySign(b, sb); 103da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 104da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#if 1 105da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int c = (int)(((SkLONGLONG)a * b) >> 16); 106da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 107da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed return SkApplySign(c, sa ^ sb); 108da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#else 109da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkLONGLONG ab = (SkLONGLONG)a * b; 110da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed if (sa ^ sb) { 111da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed ab = -ab; 112da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 113da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed return ab >> 16; 114da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#endif 115da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed} 116da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#endif 117da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 118da3b8b285a5e3e6f344461d67e3370b27701756dMike Reedstatic void check_length(skiatest::Reporter* reporter, 119da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed const SkPoint& p, SkScalar targetLen) { 120da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#ifdef SK_CAN_USE_FLOAT 121da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed float x = SkScalarToFloat(p.fX); 122da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed float y = SkScalarToFloat(p.fY); 123da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed float len = sk_float_sqrt(x*x + y*y); 124da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 125da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed len /= SkScalarToFloat(targetLen); 126da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 127da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, len > 0.999f && len < 1.001f); 128da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#endif 129da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed} 130da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 131da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#if defined(SK_CAN_USE_FLOAT) 132da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 133da3b8b285a5e3e6f344461d67e3370b27701756dMike Reedstatic float nextFloat(SkRandom& rand) { 134da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFloatIntUnion data; 135da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed data.fSignBitInt = rand.nextU(); 136da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed return data.fFloat; 137da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed} 138da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 139da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed/* returns true if a == b as resulting from (int)x. Since it is undefined 140da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed what to do if the float exceeds 2^32-1, we check for that explicitly. 141da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed */ 142da3b8b285a5e3e6f344461d67e3370b27701756dMike Reedstatic bool equal_float_native_skia(float x, uint32_t ni, uint32_t si) { 143da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed if (!(x == x)) { // NAN 144da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed return si == SK_MaxS32 || si == SK_MinS32; 145da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 146da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed // for out of range, C is undefined, but skia always should return NaN32 147da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed if (x > SK_MaxS32) { 148da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed return si == SK_MaxS32; 149da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 150da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed if (x < -SK_MaxS32) { 151da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed return si == SK_MinS32; 152da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 153da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed return si == ni; 154da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed} 155da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 156da3b8b285a5e3e6f344461d67e3370b27701756dMike Reedstatic void assert_float_equal(skiatest::Reporter* reporter, const char op[], 157da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed float x, uint32_t ni, uint32_t si) { 158da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed if (!equal_float_native_skia(x, ni, si)) { 159da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkString desc; 160da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed desc.printf("%s float %g bits %x native %x skia %x\n", op, x, ni, si); 161da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed reporter->reportFailed(desc); 162da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 163da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed} 164da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 165da3b8b285a5e3e6f344461d67e3370b27701756dMike Reedstatic void test_float_cast(skiatest::Reporter* reporter, float x) { 166da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int ix = (int)x; 167da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int iix = SkFloatToIntCast(x); 168da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed assert_float_equal(reporter, "cast", x, ix, iix); 169da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed} 170da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 171da3b8b285a5e3e6f344461d67e3370b27701756dMike Reedstatic void test_float_floor(skiatest::Reporter* reporter, float x) { 172da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int ix = (int)floor(x); 173da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int iix = SkFloatToIntFloor(x); 174da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed assert_float_equal(reporter, "floor", x, ix, iix); 175da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed} 176da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 177da3b8b285a5e3e6f344461d67e3370b27701756dMike Reedstatic void test_float_round(skiatest::Reporter* reporter, float x) { 178da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed double xx = x + 0.5; // need intermediate double to avoid temp loss 179da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int ix = (int)floor(xx); 180da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int iix = SkFloatToIntRound(x); 181da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed assert_float_equal(reporter, "round", x, ix, iix); 182da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed} 183da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 184da3b8b285a5e3e6f344461d67e3370b27701756dMike Reedstatic void test_float_ceil(skiatest::Reporter* reporter, float x) { 185da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int ix = (int)ceil(x); 186da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int iix = SkFloatToIntCeil(x); 187da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed assert_float_equal(reporter, "ceil", x, ix, iix); 188da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed} 189da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 190da3b8b285a5e3e6f344461d67e3370b27701756dMike Reedstatic void test_float_conversions(skiatest::Reporter* reporter, float x) { 191da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed test_float_cast(reporter, x); 192da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed test_float_floor(reporter, x); 193da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed test_float_round(reporter, x); 194da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed test_float_ceil(reporter, x); 195da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed} 196da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 197da3b8b285a5e3e6f344461d67e3370b27701756dMike Reedstatic void test_int2float(skiatest::Reporter* reporter, int ival) { 198da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed float x0 = (float)ival; 199da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed float x1 = SkIntToFloatCast(ival); 200da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed float x2 = SkIntToFloatCast_NoOverflowCheck(ival); 201da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, x0 == x1); 202da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, x0 == x2); 203da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed} 204da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 205da3b8b285a5e3e6f344461d67e3370b27701756dMike Reedstatic void unittest_fastfloat(skiatest::Reporter* reporter) { 206da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkRandom rand; 207da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed size_t i; 208da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 209da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed static const float gFloats[] = { 210da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 0.f, 1.f, 0.5f, 0.499999f, 0.5000001f, 1.f/3, 211da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 0.000000001f, 1000000000.f, // doesn't overflow 212da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 0.0000000001f, 10000000000.f // does overflow 213da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed }; 214da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed for (i = 0; i < SK_ARRAY_COUNT(gFloats); i++) { 215da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed test_float_conversions(reporter, gFloats[i]); 216da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed test_float_conversions(reporter, -gFloats[i]); 217da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 218da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 219da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed for (int outer = 0; outer < 100; outer++) { 220da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed rand.setSeed(outer); 221da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed for (i = 0; i < 100000; i++) { 222da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed float x = nextFloat(rand); 223da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed test_float_conversions(reporter, x); 224da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 225da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 226da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed test_int2float(reporter, 0); 227da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed test_int2float(reporter, 1); 228da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed test_int2float(reporter, -1); 229da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed for (i = 0; i < 100000; i++) { 230da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed // for now only test ints that are 24bits or less, since we don't 231da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed // round (down) large ints the same as IEEE... 232da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int ival = rand.nextU() & 0xFFFFFF; 233da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed test_int2float(reporter, ival); 234da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed test_int2float(reporter, -ival); 235da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 236da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 237da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed} 238da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 23905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#ifdef SK_SCALAR_IS_FLOAT 24005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic float make_zero() { 24105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger return sk_float_sin(0); 24205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger} 24305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#endif 24405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 24505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic void unittest_isfinite(skiatest::Reporter* reporter) { 24605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#ifdef SK_SCALAR_IS_FLOAT 2470199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger float nan = sk_float_asin(2); 24805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger float inf = 1.0 / make_zero(); 24905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger float big = 3.40282e+038; 25005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 25105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, !SkScalarIsNaN(inf)); 25205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, !SkScalarIsNaN(-inf)); 25305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, !SkScalarIsFinite(inf)); 25405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, !SkScalarIsFinite(-inf)); 25505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#else 25605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkFixed nan = SK_FixedNaN; 25705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger SkFixed big = SK_FixedMax; 25805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#endif 25905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 26005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, SkScalarIsNaN(nan)); 26105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, !SkScalarIsNaN(big)); 26205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, !SkScalarIsNaN(-big)); 26305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, !SkScalarIsNaN(0)); 26405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 26505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, !SkScalarIsFinite(nan)); 26605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, SkScalarIsFinite(big)); 26705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, SkScalarIsFinite(-big)); 26805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, SkScalarIsFinite(0)); 26905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger} 27005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 271da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#endif 272da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 273da3b8b285a5e3e6f344461d67e3370b27701756dMike Reedstatic void test_muldiv255(skiatest::Reporter* reporter) { 274da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#ifdef SK_CAN_USE_FLOAT 275da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed for (int a = 0; a <= 255; a++) { 276da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed for (int b = 0; b <= 255; b++) { 277da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int ab = a * b; 278da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed float s = ab / 255.0f; 279da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int round = (int)floorf(s + 0.5f); 280da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int trunc = (int)floorf(s); 281da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 282da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int iround = SkMulDiv255Round(a, b); 283da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int itrunc = SkMulDiv255Trunc(a, b); 284da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 285da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, iround == round); 286da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, itrunc == trunc); 287da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 288da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, itrunc <= iround); 289da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, iround <= a); 290da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, iround <= b); 291da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 292da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 293da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#endif 294da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed} 295da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 29605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerstatic void test_muldiv255ceiling(skiatest::Reporter* reporter) { 29705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger for (int c = 0; c <= 255; c++) { 29805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger for (int a = 0; a <= 255; a++) { 29905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger int product = (c * a + 255); 30005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger int expected_ceiling = (product + (product >> 8)) >> 8; 30105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger int webkit_ceiling = (c * a + 254) / 255; 30205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, expected_ceiling == webkit_ceiling); 30305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger int skia_ceiling = SkMulDiv255Ceiling(c, a); 30405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger REPORTER_ASSERT(reporter, skia_ceiling == webkit_ceiling); 30505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 30605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 30705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger} 30805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 3091c980e0d7772f05f570ae0227d91635f017c2227Mike Reedstatic void test_copysign(skiatest::Reporter* reporter) { 3101c980e0d7772f05f570ae0227d91635f017c2227Mike Reed static const int32_t gTriples[] = { 3111c980e0d7772f05f570ae0227d91635f017c2227Mike Reed // x, y, expected result 3121c980e0d7772f05f570ae0227d91635f017c2227Mike Reed 0, 0, 0, 3131c980e0d7772f05f570ae0227d91635f017c2227Mike Reed 0, 1, 0, 3141c980e0d7772f05f570ae0227d91635f017c2227Mike Reed 0, -1, 0, 3151c980e0d7772f05f570ae0227d91635f017c2227Mike Reed 1, 0, 1, 3161c980e0d7772f05f570ae0227d91635f017c2227Mike Reed 1, 1, 1, 3171c980e0d7772f05f570ae0227d91635f017c2227Mike Reed 1, -1, -1, 3181c980e0d7772f05f570ae0227d91635f017c2227Mike Reed -1, 0, 1, 3191c980e0d7772f05f570ae0227d91635f017c2227Mike Reed -1, 1, 1, 3201c980e0d7772f05f570ae0227d91635f017c2227Mike Reed -1, -1, -1, 3211c980e0d7772f05f570ae0227d91635f017c2227Mike Reed }; 3221c980e0d7772f05f570ae0227d91635f017c2227Mike Reed for (size_t i = 0; i < SK_ARRAY_COUNT(gTriples); i += 3) { 3231c980e0d7772f05f570ae0227d91635f017c2227Mike Reed REPORTER_ASSERT(reporter, 3241c980e0d7772f05f570ae0227d91635f017c2227Mike Reed SkCopySign32(gTriples[i], gTriples[i+1]) == gTriples[i+2]); 3251c980e0d7772f05f570ae0227d91635f017c2227Mike Reed#ifdef SK_CAN_USE_FLOAT 3261c980e0d7772f05f570ae0227d91635f017c2227Mike Reed float x = (float)gTriples[i]; 3271c980e0d7772f05f570ae0227d91635f017c2227Mike Reed float y = (float)gTriples[i+1]; 3281c980e0d7772f05f570ae0227d91635f017c2227Mike Reed float expected = (float)gTriples[i+2]; 3291c980e0d7772f05f570ae0227d91635f017c2227Mike Reed REPORTER_ASSERT(reporter, sk_float_copysign(x, y) == expected); 3301c980e0d7772f05f570ae0227d91635f017c2227Mike Reed#endif 3311c980e0d7772f05f570ae0227d91635f017c2227Mike Reed } 3321c980e0d7772f05f570ae0227d91635f017c2227Mike Reed 3331c980e0d7772f05f570ae0227d91635f017c2227Mike Reed SkRandom rand; 3341c980e0d7772f05f570ae0227d91635f017c2227Mike Reed for (int j = 0; j < 1000; j++) { 3351c980e0d7772f05f570ae0227d91635f017c2227Mike Reed int ix = rand.nextS(); 3361c980e0d7772f05f570ae0227d91635f017c2227Mike Reed REPORTER_ASSERT(reporter, SkCopySign32(ix, ix) == ix); 3371c980e0d7772f05f570ae0227d91635f017c2227Mike Reed REPORTER_ASSERT(reporter, SkCopySign32(ix, -ix) == -ix); 3381c980e0d7772f05f570ae0227d91635f017c2227Mike Reed REPORTER_ASSERT(reporter, SkCopySign32(-ix, ix) == ix); 3391c980e0d7772f05f570ae0227d91635f017c2227Mike Reed REPORTER_ASSERT(reporter, SkCopySign32(-ix, -ix) == -ix); 3401c980e0d7772f05f570ae0227d91635f017c2227Mike Reed 3411c980e0d7772f05f570ae0227d91635f017c2227Mike Reed SkScalar sx = rand.nextSScalar1(); 3421c980e0d7772f05f570ae0227d91635f017c2227Mike Reed REPORTER_ASSERT(reporter, SkScalarCopySign(sx, sx) == sx); 3431c980e0d7772f05f570ae0227d91635f017c2227Mike Reed REPORTER_ASSERT(reporter, SkScalarCopySign(sx, -sx) == -sx); 3441c980e0d7772f05f570ae0227d91635f017c2227Mike Reed REPORTER_ASSERT(reporter, SkScalarCopySign(-sx, sx) == sx); 3451c980e0d7772f05f570ae0227d91635f017c2227Mike Reed REPORTER_ASSERT(reporter, SkScalarCopySign(-sx, -sx) == -sx); 3461c980e0d7772f05f570ae0227d91635f017c2227Mike Reed } 3471c980e0d7772f05f570ae0227d91635f017c2227Mike Reed} 3481c980e0d7772f05f570ae0227d91635f017c2227Mike Reed 349da3b8b285a5e3e6f344461d67e3370b27701756dMike Reedstatic void TestMath(skiatest::Reporter* reporter) { 350da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int i; 351da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int32_t x; 352da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkRandom rand; 353da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 354da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed // these should assert 355da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#if 0 356da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkToS8(128); 357da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkToS8(-129); 358da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkToU8(256); 359da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkToU8(-5); 360da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 361da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkToS16(32768); 362da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkToS16(-32769); 363da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkToU16(65536); 364da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkToU16(-5); 365da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 366da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed if (sizeof(size_t) > 4) { 367da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkToS32(4*1024*1024); 368da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkToS32(-4*1024*1024); 369da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkToU32(5*1024*1024); 370da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkToU32(-5); 371da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 372da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#endif 373da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 374da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed test_muldiv255(reporter); 37505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger test_muldiv255ceiling(reporter); 3761c980e0d7772f05f570ae0227d91635f017c2227Mike Reed test_copysign(reporter); 377da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 378da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed { 379da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkScalar x = SK_ScalarNaN; 380da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, SkScalarIsNaN(x)); 381da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 382da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 383da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed for (i = 1; i <= 10; i++) { 384da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed x = SkCubeRootBits(i*i*i, 11); 385da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, x == i); 386da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 387da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 388da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed x = SkFixedSqrt(SK_Fixed1); 389da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, x == SK_Fixed1); 390da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed x = SkFixedSqrt(SK_Fixed1/4); 391da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, x == SK_Fixed1/2); 392da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed x = SkFixedSqrt(SK_Fixed1*4); 393da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, x == SK_Fixed1*2); 394da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 395da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed x = SkFractSqrt(SK_Fract1); 396da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, x == SK_Fract1); 397da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed x = SkFractSqrt(SK_Fract1/4); 398da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, x == SK_Fract1/2); 399da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed x = SkFractSqrt(SK_Fract1/16); 400da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, x == SK_Fract1/4); 401da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 402da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed for (i = 1; i < 100; i++) { 403da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed x = SkFixedSqrt(SK_Fixed1 * i * i); 404da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, x == SK_Fixed1 * i); 405da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 406da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 407da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed for (i = 0; i < 1000; i++) { 408da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int value = rand.nextS16(); 409da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int max = rand.nextU16(); 410da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 411da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int clamp = SkClampMax(value, max); 412da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int clamp2 = value < 0 ? 0 : (value > max ? max : value); 413da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, clamp == clamp2); 414da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 415da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 4168e048c19870a898cecdde3b3c0d2d512e6f372c0Mike Reed for (i = 0; i < 10000; i++) { 417da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkPoint p; 418da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 419da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed p.setLength(rand.nextS(), rand.nextS(), SK_Scalar1); 420da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed check_length(reporter, p, SK_Scalar1); 421da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed p.setLength(rand.nextS() >> 13, rand.nextS() >> 13, SK_Scalar1); 422da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed check_length(reporter, p, SK_Scalar1); 423da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 424da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 425da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed { 426da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFixed result = SkFixedDiv(100, 100); 427da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, result == SK_Fixed1); 428da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed result = SkFixedDiv(1, SK_Fixed1); 429da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, result == 1); 430da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 431da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 432da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#ifdef SK_CAN_USE_FLOAT 433da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed unittest_fastfloat(reporter); 43405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger unittest_isfinite(reporter); 435da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#endif 436da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 437da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#ifdef SkLONGLONG 4388e048c19870a898cecdde3b3c0d2d512e6f372c0Mike Reed for (i = 0; i < 10000; i++) { 439da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFixed numer = rand.nextS(); 440da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFixed denom = rand.nextS(); 441da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFixed result = SkFixedDiv(numer, denom); 442da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkLONGLONG check = ((SkLONGLONG)numer << 16) / denom; 443da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 444da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed (void)SkCLZ(numer); 445da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed (void)SkCLZ(denom); 446da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 447da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, result != (SkFixed)SK_NaN32); 448da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed if (check > SK_MaxS32) { 449da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed check = SK_MaxS32; 450da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } else if (check < -SK_MaxS32) { 451da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed check = SK_MinS32; 452da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 453da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, result == (int32_t)check); 454da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 455da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed result = SkFractDiv(numer, denom); 456da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed check = ((SkLONGLONG)numer << 30) / denom; 457da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 458da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, result != (SkFixed)SK_NaN32); 459da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed if (check > SK_MaxS32) { 460da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed check = SK_MaxS32; 461da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } else if (check < -SK_MaxS32) { 462da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed check = SK_MinS32; 463da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 464da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, result == (int32_t)check); 465da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 466da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed // make them <= 2^24, so we don't overflow in fixmul 467da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed numer = numer << 8 >> 8; 468da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed denom = denom << 8 >> 8; 469da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 470da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed result = SkFixedMul(numer, denom); 471da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFixed r2 = symmetric_fixmul(numer, denom); 472da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed // SkASSERT(result == r2); 473da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 474da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed result = SkFixedMul(numer, numer); 475da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed r2 = SkFixedSquare(numer); 476da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, result == r2); 477da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 478da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#ifdef SK_CAN_USE_FLOAT 479da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed if (numer >= 0 && denom >= 0) { 480da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFixed mean = SkFixedMean(numer, denom); 481da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed float prod = SkFixedToFloat(numer) * SkFixedToFloat(denom); 482da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed float fm = sk_float_sqrt(sk_float_abs(prod)); 483da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFixed mean2 = SkFloatToFixed(fm); 484da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int diff = SkAbs32(mean - mean2); 485da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, diff <= 1); 486da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 487da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 488da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed { 489da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFixed mod = SkFixedMod(numer, denom); 490da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed float n = SkFixedToFloat(numer); 491da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed float d = SkFixedToFloat(denom); 492da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed float m = sk_float_mod(n, d); 493da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed // ensure the same sign 494da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, mod == 0 || (mod < 0) == (m < 0)); 495da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int diff = SkAbs32(mod - SkFloatToFixed(m)); 496da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, (diff >> 7) == 0); 497da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 498da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#endif 499da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 500da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#endif 501da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 502da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#ifdef SK_CAN_USE_FLOAT 5038e048c19870a898cecdde3b3c0d2d512e6f372c0Mike Reed for (i = 0; i < 10000; i++) { 504da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFract x = rand.nextU() >> 1; 505da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed double xx = (double)x / SK_Fract1; 506da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFract xr = SkFractSqrt(x); 507da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFract check = SkFloatToFract(sqrt(xx)); 508da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, xr == check || 509da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed xr == check-1 || 510da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed xr == check+1); 511da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 512da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed xr = SkFixedSqrt(x); 513da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed xx = (double)x / SK_Fixed1; 514da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed check = SkFloatToFixed(sqrt(xx)); 515da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, xr == check || xr == check-1); 516da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 517da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed xr = SkSqrt32(x); 518da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed xx = (double)x; 519da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed check = (int32_t)sqrt(xx); 520da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, xr == check || xr == check-1); 521da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 522da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#endif 523da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 524da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#if !defined(SK_SCALAR_IS_FLOAT) && defined(SK_CAN_USE_FLOAT) 525da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed { 526da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFixed s, c; 527da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed s = SkFixedSinCos(0, &c); 528da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, s == 0); 529da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed REPORTER_ASSERT(reporter, c == SK_Fixed1); 530da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 531da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 532da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed int maxDiff = 0; 5338e048c19870a898cecdde3b3c0d2d512e6f372c0Mike Reed for (i = 0; i < 1000; i++) { 534da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFixed rads = rand.nextS() >> 10; 535da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed double frads = SkFixedToFloat(rads); 536da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 537da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFixed s, c; 538da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed s = SkScalarSinCos(rads, &c); 539da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 540da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed double fs = sin(frads); 541da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed double fc = cos(frads); 542da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 543da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFixed is = SkFloatToFixed(fs); 544da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkFixed ic = SkFloatToFixed(fc); 545da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 546da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed maxDiff = SkMax32(maxDiff, SkAbs32(is - s)); 547da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed maxDiff = SkMax32(maxDiff, SkAbs32(ic - c)); 548da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed } 549da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed SkDebugf("SinCos: maximum error = %d\n", maxDiff); 550da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#endif 55187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 5521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_SCALAR_IS_FLOAT 5531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger test_blend(reporter); 5541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 5551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // disable for now 5571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// test_blend31(); 558da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed} 559da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed 560da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#include "TestClassDef.h" 561da3b8b285a5e3e6f344461d67e3370b27701756dMike ReedDEFINE_TESTCLASS("Math", MathTestClass, TestMath) 562