diff options
author | reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2009-02-27 16:24:51 +0000 |
---|---|---|
committer | reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2009-02-27 16:24:51 +0000 |
commit | ed673310e2551e64d8196f7776d7d4c92085f8c2 (patch) | |
tree | ac5a737aaaf66c97be7109eb980beadd35e30e25 /src/core/SkMath.cpp | |
parent | 3469c76c40790b409621fd7eff34f56240718549 (diff) |
add initial unittest framework (tests)
move some previous unittests out of core classes and into tests
git-svn-id: http://skia.googlecode.com/svn/trunk@96 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkMath.cpp')
-rw-r--r-- | src/core/SkMath.cpp | 393 |
1 files changed, 0 insertions, 393 deletions
diff --git a/src/core/SkMath.cpp b/src/core/SkMath.cpp index e0babeb5e7..649b51890a 100644 --- a/src/core/SkMath.cpp +++ b/src/core/SkMath.cpp @@ -543,396 +543,3 @@ SkFixed SkFixedATan2(SkFixed y, SkFixed x) { return SkCordicATan2(y, x); } SkFixed SkFixedExp(SkFixed x) { return SkCordicExp(x); } SkFixed SkFixedLog(SkFixed x) { return SkCordicLog(x); } -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -#ifdef SK_DEBUG - -#include "SkRandom.h" - -#if defined(SkLONGLONG) && defined(SK_SUPPORT_UNITTEST) -static int symmetric_fixmul(int a, int b) { - int sa = SkExtractSign(a); - int sb = SkExtractSign(b); - - a = SkApplySign(a, sa); - b = SkApplySign(b, sb); - -#if 1 - int c = (int)(((SkLONGLONG)a * b) >> 16); - - return SkApplySign(c, sa ^ sb); -#else - SkLONGLONG ab = (SkLONGLONG)a * b; - if (sa ^ sb) { - ab = -ab; - } - return ab >> 16; -#endif -} -#endif - -#include "SkPoint.h" - -#ifdef SK_SUPPORT_UNITTEST -static void check_length(const SkPoint& p, SkScalar targetLen) { -#ifdef SK_CAN_USE_FLOAT - float x = SkScalarToFloat(p.fX); - float y = SkScalarToFloat(p.fY); - float len = sk_float_sqrt(x*x + y*y); - - len /= SkScalarToFloat(targetLen); - - SkASSERT(len > 0.999f && len < 1.001f); -#endif -} -#endif - -#if defined(SK_CAN_USE_FLOAT) && defined(SK_SUPPORT_UNITTEST) - -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 - -#ifdef SK_SUPPORT_UNITTEST -static void test_muldiv255() { -#ifdef SK_CAN_USE_FLOAT - for (int a = 0; a <= 255; a++) { - for (int b = 0; b <= 255; b++) { - int ab = a * b; - float s = ab / 255.0f; - int round = (int)floorf(s + 0.5f); - int trunc = (int)floorf(s); - - int iround = SkMulDiv255Round(a, b); - int itrunc = SkMulDiv255Trunc(a, b); - - SkASSERT(iround == round); - SkASSERT(itrunc == trunc); - - SkASSERT(itrunc <= iround); - SkASSERT(iround <= a); - SkASSERT(iround <= b); - } - } -#endif -} -#endif - -void SkMath::UnitTest() { -#ifdef SK_SUPPORT_UNITTEST - int i; - int32_t x; - SkRandom rand; - - SkToS8(127); SkToS8(-128); SkToU8(255); - SkToS16(32767); SkToS16(-32768); SkToU16(65535); - SkToS32(2*1024*1024); SkToS32(-2*1024*1024); SkToU32(4*1024*1024); - - SkCordic_UnitTest(); - - // these should assert -#if 0 - SkToS8(128); - SkToS8(-129); - SkToU8(256); - SkToU8(-5); - - SkToS16(32768); - SkToS16(-32769); - SkToU16(65536); - SkToU16(-5); - - if (sizeof(size_t) > 4) { - SkToS32(4*1024*1024); - SkToS32(-4*1024*1024); - SkToU32(5*1024*1024); - SkToU32(-5); - } -#endif - - test_muldiv255(); - -#ifdef SK_DEBUG - { - SkScalar x = SK_ScalarNaN; - SkASSERT(SkScalarIsNaN(x)); - } -#endif - - for (i = 1; i <= 10; i++) { - x = SkCubeRootBits(i*i*i, 11); - SkASSERT(x == i); - } - - x = SkFixedSqrt(SK_Fixed1); - SkASSERT(x == SK_Fixed1); - x = SkFixedSqrt(SK_Fixed1/4); - SkASSERT(x == SK_Fixed1/2); - x = SkFixedSqrt(SK_Fixed1*4); - SkASSERT(x == SK_Fixed1*2); - - x = SkFractSqrt(SK_Fract1); - SkASSERT(x == SK_Fract1); - x = SkFractSqrt(SK_Fract1/4); - SkASSERT(x == SK_Fract1/2); - x = SkFractSqrt(SK_Fract1/16); - SkASSERT(x == SK_Fract1/4); - - for (i = 1; i < 100; i++) { - x = SkFixedSqrt(SK_Fixed1 * i * i); - SkASSERT(x == SK_Fixed1 * i); - } - - for (i = 0; i < 1000; i++) { - int value = rand.nextS16(); - int max = rand.nextU16(); - - int clamp = SkClampMax(value, max); - int clamp2 = value < 0 ? 0 : (value > max ? max : value); - SkASSERT(clamp == clamp2); - } - - for (i = 0; i < 100000; i++) { - SkPoint p; - - p.setLength(rand.nextS(), rand.nextS(), SK_Scalar1); - check_length(p, SK_Scalar1); - p.setLength(rand.nextS() >> 13, rand.nextS() >> 13, SK_Scalar1); - check_length(p, SK_Scalar1); - } - - { - SkFixed result = SkFixedDiv(100, 100); - SkASSERT(result == SK_Fixed1); - result = SkFixedDiv(1, SK_Fixed1); - SkASSERT(result == 1); - } - -#ifdef SK_CAN_USE_FLOAT - unittest_fastfloat(); -#endif - -#ifdef SkLONGLONG - for (i = 0; i < 100000; i++) { - SkFixed numer = rand.nextS(); - SkFixed denom = rand.nextS(); - SkFixed result = SkFixedDiv(numer, denom); - SkLONGLONG check = ((SkLONGLONG)numer << 16) / denom; - - (void)SkCLZ(numer); - (void)SkCLZ(denom); - - SkASSERT(result != (SkFixed)SK_NaN32); - if (check > SK_MaxS32) { - check = SK_MaxS32; - } else if (check < -SK_MaxS32) { - check = SK_MinS32; - } - SkASSERT(result == (int32_t)check); - - result = SkFractDiv(numer, denom); - check = ((SkLONGLONG)numer << 30) / denom; - - SkASSERT(result != (SkFixed)SK_NaN32); - if (check > SK_MaxS32) { - check = SK_MaxS32; - } else if (check < -SK_MaxS32) { - check = SK_MinS32; - } - SkASSERT(result == (int32_t)check); - - // make them <= 2^24, so we don't overflow in fixmul - numer = numer << 8 >> 8; - denom = denom << 8 >> 8; - - result = SkFixedMul(numer, denom); - SkFixed r2 = symmetric_fixmul(numer, denom); -// SkASSERT(result == r2); - - result = SkFixedMul(numer, numer); - r2 = SkFixedSquare(numer); - SkASSERT(result == r2); - -#ifdef SK_CAN_USE_FLOAT - if (numer >= 0 && denom >= 0) { - SkFixed mean = SkFixedMean(numer, denom); - float fm = sk_float_sqrt(sk_float_abs(SkFixedToFloat(numer) * SkFixedToFloat(denom))); - SkFixed mean2 = SkFloatToFixed(fm); - int diff = SkAbs32(mean - mean2); - SkASSERT(diff <= 1); - } - - { - SkFixed mod = SkFixedMod(numer, denom); - float n = SkFixedToFloat(numer); - float d = SkFixedToFloat(denom); - float m = sk_float_mod(n, d); -#if 0 - SkDebugf("%g mod %g = %g [%g]\n", - SkFixedToFloat(numer), SkFixedToFloat(denom), - SkFixedToFloat(mod), m); -#endif - SkASSERT(mod == 0 || (mod < 0) == (m < 0)); // ensure the same sign - int diff = SkAbs32(mod - SkFloatToFixed(m)); - SkASSERT((diff >> 7) == 0); - } -#endif - } -#endif - -#ifdef SK_CAN_USE_FLOAT - for (i = 0; i < 100000; i++) { - SkFract x = rand.nextU() >> 1; - double xx = (double)x / SK_Fract1; - SkFract xr = SkFractSqrt(x); - SkFract check = SkFloatToFract(sqrt(xx)); - SkASSERT(xr == check || xr == check-1 || xr == check+1); - - xr = SkFixedSqrt(x); - xx = (double)x / SK_Fixed1; - check = SkFloatToFixed(sqrt(xx)); - SkASSERT(xr == check || xr == check-1); - - xr = SkSqrt32(x); - xx = (double)x; - check = (int32_t)sqrt(xx); - SkASSERT(xr == check || xr == check-1); - } -#endif - -#if !defined(SK_SCALAR_IS_FLOAT) && defined(SK_CAN_USE_FLOAT) - { - SkFixed s, c; - s = SkFixedSinCos(0, &c); - SkASSERT(s == 0); - SkASSERT(c == SK_Fixed1); - } - - int maxDiff = 0; - for (i = 0; i < 10000; i++) { - SkFixed rads = rand.nextS() >> 10; - double frads = SkFixedToFloat(rads); - - SkFixed s, c; - s = SkScalarSinCos(rads, &c); - - double fs = sin(frads); - double fc = cos(frads); - - SkFixed is = SkFloatToFixed(fs); - SkFixed ic = SkFloatToFixed(fc); - - maxDiff = SkMax32(maxDiff, SkAbs32(is - s)); - maxDiff = SkMax32(maxDiff, SkAbs32(ic - c)); - } - SkDebugf("SinCos: maximum error = %d\n", maxDiff); -#endif -#endif -} - -#endif |