diff options
author | brettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-12-12 21:01:41 +0000 |
---|---|---|
committer | brettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-12-12 21:01:41 +0000 |
commit | 52e935d04c59135739c3a68fb6e19d313dc6d5ad (patch) | |
tree | 95f7ab178b045bef4456cbf92c6aa7e476becd99 /skia/corecg/SkMath.cpp | |
parent | 30fab79877b4bb067944b74d98346ac9bb6bfc7e (diff) | |
download | chromium_src-52e935d04c59135739c3a68fb6e19d313dc6d5ad.zip chromium_src-52e935d04c59135739c3a68fb6e19d313dc6d5ad.tar.gz chromium_src-52e935d04c59135739c3a68fb6e19d313dc6d5ad.tar.bz2 |
New drop of Skia. This is up to CL 121320.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@6925 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia/corecg/SkMath.cpp')
-rw-r--r-- | skia/corecg/SkMath.cpp | 122 |
1 files changed, 117 insertions, 5 deletions
diff --git a/skia/corecg/SkMath.cpp b/skia/corecg/SkMath.cpp index 42ea107..c627d9b 100644 --- a/skia/corecg/SkMath.cpp +++ b/skia/corecg/SkMath.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2008 Google Inc. + * Copyright (C) 2006-2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ #include "SkMath.h" #include "SkCordic.h" +#include "SkFloatBits.h" #include "SkFloatingPoint.h" #include "Sk64.h" #include "SkScalar.h" @@ -214,7 +215,7 @@ int SkFixedMulCommon(SkFixed a, int b, int bias) { #endif SkFixed SkFixedFastInvert(SkFixed x) { -/* Adapted (stolen) from Mathias' gglRecip() +/* Adapted (stolen) from gglRecip() */ if (x == SK_Fixed1) { @@ -585,6 +586,116 @@ static void check_length(const SkPoint& p, SkScalar targetLen) { } #endif +#ifdef SK_CAN_USE_FLOAT + +static float nextFloat(SkRandom& rand) { + SkFloatIntUnion data; + data.fSignBitInt = rand.nextU(); + return data.fFloat; +} + +/* returns true if a == b as resulting from (int)x. Since it is undefined + what to do if the float exceeds 2^32-1, we check for that explicitly. +*/ +static bool equal_float_native_skia(float x, uint32_t ni, uint32_t si) { + if (!(x == x)) { // NAN + return si == SK_MaxS32 || si == SK_MinS32; + } + // for out of range, C is undefined, but skia always should return NaN32 + if (x > SK_MaxS32) { + return si == SK_MaxS32; + } + if (x < -SK_MaxS32) { + return si == SK_MinS32; + } + return si == ni; +} + +static void assert_float_equal(const char op[], float x, uint32_t ni, + uint32_t si) { + if (!equal_float_native_skia(x, ni, si)) { + SkDebugf("-- %s float %g bits %x native %x skia %x\n", op, x, ni, si); + SkASSERT(!"oops"); + } +} + +static void test_float_cast(float x) { + int ix = (int)x; + int iix = SkFloatToIntCast(x); + assert_float_equal("cast", x, ix, iix); +} + +static void test_float_floor(float x) { + int ix = (int)floor(x); + int iix = SkFloatToIntFloor(x); + assert_float_equal("floor", x, ix, iix); +} + +static void test_float_round(float x) { + double xx = x + 0.5; // need intermediate double to avoid temp loss + int ix = (int)floor(xx); + int iix = SkFloatToIntRound(x); + assert_float_equal("round", x, ix, iix); +} + +static void test_float_ceil(float x) { + int ix = (int)ceil(x); + int iix = SkFloatToIntCeil(x); + assert_float_equal("ceil", x, ix, iix); +} + +static void test_float_conversions(float x) { + test_float_cast(x); + test_float_floor(x); + test_float_round(x); + test_float_ceil(x); +} + +static void test_int2float(int ival) { + float x0 = (float)ival; + float x1 = SkIntToFloatCast(ival); + float x2 = SkIntToFloatCast_NoOverflowCheck(ival); + SkASSERT(x0 == x1); + SkASSERT(x0 == x2); +} + +static void unittest_fastfloat() { + SkRandom rand; + size_t i; + + static const float gFloats[] = { + 0.f, 1.f, 0.5f, 0.499999f, 0.5000001f, 1.f/3, + 0.000000001f, 1000000000.f, // doesn't overflow + 0.0000000001f, 10000000000.f // does overflow + }; + for (i = 0; i < SK_ARRAY_COUNT(gFloats); i++) { +// SkDebugf("---- test floats %g %d\n", gFloats[i], (int)gFloats[i]); + test_float_conversions(gFloats[i]); + test_float_conversions(-gFloats[i]); + } + + for (int outer = 0; outer < 100; outer++) { + rand.setSeed(outer); + for (i = 0; i < 100000; i++) { + float x = nextFloat(rand); + test_float_conversions(x); + } + + test_int2float(0); + test_int2float(1); + test_int2float(-1); + for (i = 0; i < 100000; i++) { + // for now only test ints that are 24bits or less, since we don't + // round (down) large ints the same as IEEE... + int ival = rand.nextU() & 0xFFFFFF; + test_int2float(ival); + test_int2float(-ival); + } + } +} + +#endif + static void test_muldiv255() { for (int a = 0; a <= 255; a++) { for (int b = 0; b <= 255; b++) { @@ -606,7 +717,7 @@ static void test_muldiv255() { } } -void SkMath::UnitTest() { +void SkMath::UnitTest() { #ifdef SK_SUPPORT_UNITTEST int i; int32_t x; @@ -696,8 +807,10 @@ void SkMath::UnitTest() { SkASSERT(result == 1); } +#ifdef SK_CAN_USE_FLOAT + unittest_fastfloat(); +#endif - #ifdef SkLONGLONG for (i = 0; i < 100000; i++) { SkFixed numer = rand.nextS(); @@ -817,4 +930,3 @@ void SkMath::UnitTest() { } #endif - |