1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 #include "Test.h" 9 #include "SkFloatBits.h" 10 #include "SkFloatingPoint.h" 11 #include "SkMathPriv.h" 12 #include "SkPoint.h" 13 #include "SkRandom.h" 14 #include "SkColorPriv.h" 15 16 static void test_clz(skiatest::Reporter* reporter) { 17 REPORTER_ASSERT(reporter, 32 == SkCLZ(0)); 18 REPORTER_ASSERT(reporter, 31 == SkCLZ(1)); 19 REPORTER_ASSERT(reporter, 1 == SkCLZ(1 << 30)); 20 REPORTER_ASSERT(reporter, 0 == SkCLZ(~0U)); 21 22 SkRandom rand; 23 for (int i = 0; i < 1000; ++i) { 24 uint32_t mask = rand.nextU(); 25 // need to get some zeros for testing, but in some obscure way so the 26 // compiler won't "see" that, and work-around calling the functions. 27 mask >>= (mask & 31); 28 int intri = SkCLZ(mask); 29 int porta = SkCLZ_portable(mask); 30 REPORTER_ASSERT(reporter, intri == porta); 31 } 32 } 33 34 /////////////////////////////////////////////////////////////////////////////// 35 36 static float sk_fsel(float pred, float result_ge, float result_lt) { 37 return pred >= 0 ? result_ge : result_lt; 38 } 39 40 static float fast_floor(float x) { 41 // float big = sk_fsel(x, 0x1.0p+23, -0x1.0p+23); 42 float big = sk_fsel(x, (float)(1 << 23), -(float)(1 << 23)); 43 return (float)(x + big) - big; 44 } 45 46 static float std_floor(float x) { 47 return sk_float_floor(x); 48 } 49 50 static void test_floor_value(skiatest::Reporter* reporter, float value) { 51 float fast = fast_floor(value); 52 float std = std_floor(value); 53 REPORTER_ASSERT(reporter, std == fast); 54 // SkDebugf("value[%1.9f] std[%g] fast[%g] equal[%d]\n", 55 // value, std, fast, std == fast); 56 } 57 58 static void test_floor(skiatest::Reporter* reporter) { 59 static const float gVals[] = { 60 0, 1, 1.1f, 1.01f, 1.001f, 1.0001f, 1.00001f, 1.000001f, 1.0000001f 61 }; 62 63 for (size_t i = 0; i < SK_ARRAY_COUNT(gVals); ++i) { 64 test_floor_value(reporter, gVals[i]); 65 // test_floor_value(reporter, -gVals[i]); 66 } 67 } 68 69 /////////////////////////////////////////////////////////////////////////////// 70 71 // test that SkMul16ShiftRound and SkMulDiv255Round return the same result 72 static void test_muldivround(skiatest::Reporter* reporter) { 73 #if 0 74 // this "complete" test is too slow, so we test a random sampling of it 75 76 for (int a = 0; a <= 32767; ++a) { 77 for (int b = 0; b <= 32767; ++b) { 78 unsigned prod0 = SkMul16ShiftRound(a, b, 8); 79 unsigned prod1 = SkMulDiv255Round(a, b); 80 SkASSERT(prod0 == prod1); 81 } 82 } 83 #endif 84 85 SkRandom rand; 86 for (int i = 0; i < 10000; ++i) { 87 unsigned a = rand.nextU() & 0x7FFF; 88 unsigned b = rand.nextU() & 0x7FFF; 89 90 unsigned prod0 = SkMul16ShiftRound(a, b, 8); 91 unsigned prod1 = SkMulDiv255Round(a, b); 92 93 REPORTER_ASSERT(reporter, prod0 == prod1); 94 } 95 } 96 97 static float float_blend(int src, int dst, float unit) { 98 return dst + (src - dst) * unit; 99 } 100 101 static int blend31(int src, int dst, int a31) { 102 return dst + ((src - dst) * a31 * 2114 >> 16); 103 // return dst + ((src - dst) * a31 * 33 >> 10); 104 } 105 106 static int blend31_slow(int src, int dst, int a31) { 107 int prod = src * a31 + (31 - a31) * dst + 16; 108 prod = (prod + (prod >> 5)) >> 5; 109 return prod; 110 } 111 112 static int blend31_round(int src, int dst, int a31) { 113 int prod = (src - dst) * a31 + 16; 114 prod = (prod + (prod >> 5)) >> 5; 115 return dst + prod; 116 } 117 118 static int blend31_old(int src, int dst, int a31) { 119 a31 += a31 >> 4; 120 return dst + ((src - dst) * a31 >> 5); 121 } 122 123 // suppress unused code warning 124 static int (*blend_functions[])(int, int, int) = { 125 blend31, 126 blend31_slow, 127 blend31_round, 128 blend31_old 129 }; 130 131 static void test_blend31() { 132 int failed = 0; 133 int death = 0; 134 if (false) { // avoid bit rot, suppress warning 135 failed = (*blend_functions[0])(0,0,0); 136 } 137 for (int src = 0; src <= 255; src++) { 138 for (int dst = 0; dst <= 255; dst++) { 139 for (int a = 0; a <= 31; a++) { 140 // int r0 = blend31(src, dst, a); 141 // int r0 = blend31_round(src, dst, a); 142 // int r0 = blend31_old(src, dst, a); 143 int r0 = blend31_slow(src, dst, a); 144 145 float f = float_blend(src, dst, a / 31.f); 146 int r1 = (int)f; 147 int r2 = SkScalarRoundToInt(SkFloatToScalar(f)); 148 149 if (r0 != r1 && r0 != r2) { 150 printf("src:%d dst:%d a:%d result:%d float:%g\n", 151 src, dst, a, r0, f); 152 failed += 1; 153 } 154 if (r0 > 255) { 155 death += 1; 156 printf("death src:%d dst:%d a:%d result:%d float:%g\n", 157 src, dst, a, r0, f); 158 } 159 } 160 } 161 } 162 SkDebugf("---- failed %d death %d\n", failed, death); 163 } 164 165 static void test_blend(skiatest::Reporter* reporter) { 166 for (int src = 0; src <= 255; src++) { 167 for (int dst = 0; dst <= 255; dst++) { 168 for (int a = 0; a <= 255; a++) { 169 int r0 = SkAlphaBlend255(src, dst, a); 170 float f1 = float_blend(src, dst, a / 255.f); 171 int r1 = SkScalarRoundToInt(SkFloatToScalar(f1)); 172 173 if (r0 != r1) { 174 float diff = sk_float_abs(f1 - r1); 175 diff = sk_float_abs(diff - 0.5f); 176 if (diff > (1 / 255.f)) { 177 #ifdef SK_DEBUG 178 SkDebugf("src:%d dst:%d a:%d result:%d float:%g\n", 179 src, dst, a, r0, f1); 180 #endif 181 REPORTER_ASSERT(reporter, false); 182 } 183 } 184 } 185 } 186 } 187 } 188 189 #if defined(SkLONGLONG) 190 static int symmetric_fixmul(int a, int b) { 191 int sa = SkExtractSign(a); 192 int sb = SkExtractSign(b); 193 194 a = SkApplySign(a, sa); 195 b = SkApplySign(b, sb); 196 197 #if 1 198 int c = (int)(((SkLONGLONG)a * b) >> 16); 199 200 return SkApplySign(c, sa ^ sb); 201 #else 202 SkLONGLONG ab = (SkLONGLONG)a * b; 203 if (sa ^ sb) { 204 ab = -ab; 205 } 206 return ab >> 16; 207 #endif 208 } 209 #endif 210 211 static void check_length(skiatest::Reporter* reporter, 212 const SkPoint& p, SkScalar targetLen) { 213 float x = SkScalarToFloat(p.fX); 214 float y = SkScalarToFloat(p.fY); 215 float len = sk_float_sqrt(x*x + y*y); 216 217 len /= SkScalarToFloat(targetLen); 218 219 REPORTER_ASSERT(reporter, len > 0.999f && len < 1.001f); 220 } 221 222 static float nextFloat(SkMWCRandom& rand) { 223 SkFloatIntUnion data; 224 data.fSignBitInt = rand.nextU(); 225 return data.fFloat; 226 } 227 228 /* returns true if a == b as resulting from (int)x. Since it is undefined 229 what to do if the float exceeds 2^32-1, we check for that explicitly. 230 */ 231 static bool equal_float_native_skia(float x, uint32_t ni, uint32_t si) { 232 if (!(x == x)) { // NAN 233 return ((int32_t)si) == SK_MaxS32 || ((int32_t)si) == SK_MinS32; 234 } 235 // for out of range, C is undefined, but skia always should return NaN32 236 if (x > SK_MaxS32) { 237 return ((int32_t)si) == SK_MaxS32; 238 } 239 if (x < -SK_MaxS32) { 240 return ((int32_t)si) == SK_MinS32; 241 } 242 return si == ni; 243 } 244 245 static void assert_float_equal(skiatest::Reporter* reporter, const char op[], 246 float x, uint32_t ni, uint32_t si) { 247 if (!equal_float_native_skia(x, ni, si)) { 248 SkString desc; 249 uint32_t xi = SkFloat2Bits(x); 250 desc.printf("%s float %g bits %x native %x skia %x\n", op, x, xi, ni, si); 251 reporter->reportFailed(desc); 252 } 253 } 254 255 static void test_float_cast(skiatest::Reporter* reporter, float x) { 256 int ix = (int)x; 257 int iix = SkFloatToIntCast(x); 258 assert_float_equal(reporter, "cast", x, ix, iix); 259 } 260 261 static void test_float_floor(skiatest::Reporter* reporter, float x) { 262 int ix = (int)floor(x); 263 int iix = SkFloatToIntFloor(x); 264 assert_float_equal(reporter, "floor", x, ix, iix); 265 } 266 267 static void test_float_round(skiatest::Reporter* reporter, float x) { 268 double xx = x + 0.5; // need intermediate double to avoid temp loss 269 int ix = (int)floor(xx); 270 int iix = SkFloatToIntRound(x); 271 assert_float_equal(reporter, "round", x, ix, iix); 272 } 273 274 static void test_float_ceil(skiatest::Reporter* reporter, float x) { 275 int ix = (int)ceil(x); 276 int iix = SkFloatToIntCeil(x); 277 assert_float_equal(reporter, "ceil", x, ix, iix); 278 } 279 280 static void test_float_conversions(skiatest::Reporter* reporter, float x) { 281 test_float_cast(reporter, x); 282 test_float_floor(reporter, x); 283 test_float_round(reporter, x); 284 test_float_ceil(reporter, x); 285 } 286 287 static void test_int2float(skiatest::Reporter* reporter, int ival) { 288 float x0 = (float)ival; 289 float x1 = SkIntToFloatCast(ival); 290 float x2 = SkIntToFloatCast_NoOverflowCheck(ival); 291 REPORTER_ASSERT(reporter, x0 == x1); 292 REPORTER_ASSERT(reporter, x0 == x2); 293 } 294 295 static void unittest_fastfloat(skiatest::Reporter* reporter) { 296 SkMWCRandom rand; 297 size_t i; 298 299 static const float gFloats[] = { 300 0.f, 1.f, 0.5f, 0.499999f, 0.5000001f, 1.f/3, 301 0.000000001f, 1000000000.f, // doesn't overflow 302 0.0000000001f, 10000000000.f // does overflow 303 }; 304 for (i = 0; i < SK_ARRAY_COUNT(gFloats); i++) { 305 test_float_conversions(reporter, gFloats[i]); 306 test_float_conversions(reporter, -gFloats[i]); 307 } 308 309 for (int outer = 0; outer < 100; outer++) { 310 rand.setSeed(outer); 311 for (i = 0; i < 100000; i++) { 312 float x = nextFloat(rand); 313 test_float_conversions(reporter, x); 314 } 315 316 test_int2float(reporter, 0); 317 test_int2float(reporter, 1); 318 test_int2float(reporter, -1); 319 for (i = 0; i < 100000; i++) { 320 // for now only test ints that are 24bits or less, since we don't 321 // round (down) large ints the same as IEEE... 322 int ival = rand.nextU() & 0xFFFFFF; 323 test_int2float(reporter, ival); 324 test_int2float(reporter, -ival); 325 } 326 } 327 } 328 329 #ifdef SK_SCALAR_IS_FLOAT 330 static float make_zero() { 331 return sk_float_sin(0); 332 } 333 #endif 334 335 static void unittest_isfinite(skiatest::Reporter* reporter) { 336 #ifdef SK_SCALAR_IS_FLOAT 337 float nan = sk_float_asin(2); 338 float inf = 1.0f / make_zero(); 339 float big = 3.40282e+038f; 340 341 REPORTER_ASSERT(reporter, !SkScalarIsNaN(inf)); 342 REPORTER_ASSERT(reporter, !SkScalarIsNaN(-inf)); 343 REPORTER_ASSERT(reporter, !SkScalarIsFinite(inf)); 344 REPORTER_ASSERT(reporter, !SkScalarIsFinite(-inf)); 345 #else 346 SkFixed nan = SK_FixedNaN; 347 SkFixed big = SK_FixedMax; 348 #endif 349 350 REPORTER_ASSERT(reporter, SkScalarIsNaN(nan)); 351 REPORTER_ASSERT(reporter, !SkScalarIsNaN(big)); 352 REPORTER_ASSERT(reporter, !SkScalarIsNaN(-big)); 353 REPORTER_ASSERT(reporter, !SkScalarIsNaN(0)); 354 355 REPORTER_ASSERT(reporter, !SkScalarIsFinite(nan)); 356 REPORTER_ASSERT(reporter, SkScalarIsFinite(big)); 357 REPORTER_ASSERT(reporter, SkScalarIsFinite(-big)); 358 REPORTER_ASSERT(reporter, SkScalarIsFinite(0)); 359 } 360 361 static void test_muldiv255(skiatest::Reporter* reporter) { 362 for (int a = 0; a <= 255; a++) { 363 for (int b = 0; b <= 255; b++) { 364 int ab = a * b; 365 float s = ab / 255.0f; 366 int round = (int)floorf(s + 0.5f); 367 int trunc = (int)floorf(s); 368 369 int iround = SkMulDiv255Round(a, b); 370 int itrunc = SkMulDiv255Trunc(a, b); 371 372 REPORTER_ASSERT(reporter, iround == round); 373 REPORTER_ASSERT(reporter, itrunc == trunc); 374 375 REPORTER_ASSERT(reporter, itrunc <= iround); 376 REPORTER_ASSERT(reporter, iround <= a); 377 REPORTER_ASSERT(reporter, iround <= b); 378 } 379 } 380 } 381 382 static void test_muldiv255ceiling(skiatest::Reporter* reporter) { 383 for (int c = 0; c <= 255; c++) { 384 for (int a = 0; a <= 255; a++) { 385 int product = (c * a + 255); 386 int expected_ceiling = (product + (product >> 8)) >> 8; 387 int webkit_ceiling = (c * a + 254) / 255; 388 REPORTER_ASSERT(reporter, expected_ceiling == webkit_ceiling); 389 int skia_ceiling = SkMulDiv255Ceiling(c, a); 390 REPORTER_ASSERT(reporter, skia_ceiling == webkit_ceiling); 391 } 392 } 393 } 394 395 static void test_copysign(skiatest::Reporter* reporter) { 396 static const int32_t gTriples[] = { 397 // x, y, expected result 398 0, 0, 0, 399 0, 1, 0, 400 0, -1, 0, 401 1, 0, 1, 402 1, 1, 1, 403 1, -1, -1, 404 -1, 0, 1, 405 -1, 1, 1, 406 -1, -1, -1, 407 }; 408 for (size_t i = 0; i < SK_ARRAY_COUNT(gTriples); i += 3) { 409 REPORTER_ASSERT(reporter, 410 SkCopySign32(gTriples[i], gTriples[i+1]) == gTriples[i+2]); 411 float x = (float)gTriples[i]; 412 float y = (float)gTriples[i+1]; 413 float expected = (float)gTriples[i+2]; 414 REPORTER_ASSERT(reporter, sk_float_copysign(x, y) == expected); 415 } 416 417 SkMWCRandom rand; 418 for (int j = 0; j < 1000; j++) { 419 int ix = rand.nextS(); 420 REPORTER_ASSERT(reporter, SkCopySign32(ix, ix) == ix); 421 REPORTER_ASSERT(reporter, SkCopySign32(ix, -ix) == -ix); 422 REPORTER_ASSERT(reporter, SkCopySign32(-ix, ix) == ix); 423 REPORTER_ASSERT(reporter, SkCopySign32(-ix, -ix) == -ix); 424 425 SkScalar sx = rand.nextSScalar1(); 426 REPORTER_ASSERT(reporter, SkScalarCopySign(sx, sx) == sx); 427 REPORTER_ASSERT(reporter, SkScalarCopySign(sx, -sx) == -sx); 428 REPORTER_ASSERT(reporter, SkScalarCopySign(-sx, sx) == sx); 429 REPORTER_ASSERT(reporter, SkScalarCopySign(-sx, -sx) == -sx); 430 } 431 } 432 433 static void TestMath(skiatest::Reporter* reporter) { 434 int i; 435 int32_t x; 436 SkMWCRandom rand; 437 438 // these should assert 439 #if 0 440 SkToS8(128); 441 SkToS8(-129); 442 SkToU8(256); 443 SkToU8(-5); 444 445 SkToS16(32768); 446 SkToS16(-32769); 447 SkToU16(65536); 448 SkToU16(-5); 449 450 if (sizeof(size_t) > 4) { 451 SkToS32(4*1024*1024); 452 SkToS32(-4*1024*1024); 453 SkToU32(5*1024*1024); 454 SkToU32(-5); 455 } 456 #endif 457 458 test_muldiv255(reporter); 459 test_muldiv255ceiling(reporter); 460 test_copysign(reporter); 461 462 { 463 SkScalar x = SK_ScalarNaN; 464 REPORTER_ASSERT(reporter, SkScalarIsNaN(x)); 465 } 466 467 for (i = 1; i <= 10; i++) { 468 x = SkCubeRootBits(i*i*i, 11); 469 REPORTER_ASSERT(reporter, x == i); 470 } 471 472 x = SkFixedSqrt(SK_Fixed1); 473 REPORTER_ASSERT(reporter, x == SK_Fixed1); 474 x = SkFixedSqrt(SK_Fixed1/4); 475 REPORTER_ASSERT(reporter, x == SK_Fixed1/2); 476 x = SkFixedSqrt(SK_Fixed1*4); 477 REPORTER_ASSERT(reporter, x == SK_Fixed1*2); 478 479 x = SkFractSqrt(SK_Fract1); 480 REPORTER_ASSERT(reporter, x == SK_Fract1); 481 x = SkFractSqrt(SK_Fract1/4); 482 REPORTER_ASSERT(reporter, x == SK_Fract1/2); 483 x = SkFractSqrt(SK_Fract1/16); 484 REPORTER_ASSERT(reporter, x == SK_Fract1/4); 485 486 for (i = 1; i < 100; i++) { 487 x = SkFixedSqrt(SK_Fixed1 * i * i); 488 REPORTER_ASSERT(reporter, x == SK_Fixed1 * i); 489 } 490 491 for (i = 0; i < 1000; i++) { 492 int value = rand.nextS16(); 493 int max = rand.nextU16(); 494 495 int clamp = SkClampMax(value, max); 496 int clamp2 = value < 0 ? 0 : (value > max ? max : value); 497 REPORTER_ASSERT(reporter, clamp == clamp2); 498 } 499 500 for (i = 0; i < 10000; i++) { 501 SkPoint p; 502 503 // These random values are being treated as 32-bit-patterns, not as 504 // ints; calling SkIntToScalar() here produces crashes. 505 p.setLength((SkScalar) rand.nextS(), 506 (SkScalar) rand.nextS(), 507 SK_Scalar1); 508 check_length(reporter, p, SK_Scalar1); 509 p.setLength((SkScalar) (rand.nextS() >> 13), 510 (SkScalar) (rand.nextS() >> 13), 511 SK_Scalar1); 512 check_length(reporter, p, SK_Scalar1); 513 } 514 515 { 516 SkFixed result = SkFixedDiv(100, 100); 517 REPORTER_ASSERT(reporter, result == SK_Fixed1); 518 result = SkFixedDiv(1, SK_Fixed1); 519 REPORTER_ASSERT(reporter, result == 1); 520 } 521 522 unittest_fastfloat(reporter); 523 unittest_isfinite(reporter); 524 525 #ifdef SkLONGLONG 526 for (i = 0; i < 10000; i++) { 527 SkFixed numer = rand.nextS(); 528 SkFixed denom = rand.nextS(); 529 SkFixed result = SkFixedDiv(numer, denom); 530 SkLONGLONG check = ((SkLONGLONG)numer << 16) / denom; 531 532 (void)SkCLZ(numer); 533 (void)SkCLZ(denom); 534 535 REPORTER_ASSERT(reporter, result != (SkFixed)SK_NaN32); 536 if (check > SK_MaxS32) { 537 check = SK_MaxS32; 538 } else if (check < -SK_MaxS32) { 539 check = SK_MinS32; 540 } 541 REPORTER_ASSERT(reporter, result == (int32_t)check); 542 543 result = SkFractDiv(numer, denom); 544 check = ((SkLONGLONG)numer << 30) / denom; 545 546 REPORTER_ASSERT(reporter, result != (SkFixed)SK_NaN32); 547 if (check > SK_MaxS32) { 548 check = SK_MaxS32; 549 } else if (check < -SK_MaxS32) { 550 check = SK_MinS32; 551 } 552 REPORTER_ASSERT(reporter, result == (int32_t)check); 553 554 // make them <= 2^24, so we don't overflow in fixmul 555 numer = numer << 8 >> 8; 556 denom = denom << 8 >> 8; 557 558 result = SkFixedMul(numer, denom); 559 SkFixed r2 = symmetric_fixmul(numer, denom); 560 // SkASSERT(result == r2); 561 562 result = SkFixedMul(numer, numer); 563 r2 = SkFixedSquare(numer); 564 REPORTER_ASSERT(reporter, result == r2); 565 566 if (numer >= 0 && denom >= 0) { 567 SkFixed mean = SkFixedMean(numer, denom); 568 float prod = SkFixedToFloat(numer) * SkFixedToFloat(denom); 569 float fm = sk_float_sqrt(sk_float_abs(prod)); 570 SkFixed mean2 = SkFloatToFixed(fm); 571 int diff = SkAbs32(mean - mean2); 572 REPORTER_ASSERT(reporter, diff <= 1); 573 } 574 575 { 576 SkFixed mod = SkFixedMod(numer, denom); 577 float n = SkFixedToFloat(numer); 578 float d = SkFixedToFloat(denom); 579 float m = sk_float_mod(n, d); 580 // ensure the same sign 581 REPORTER_ASSERT(reporter, mod == 0 || (mod < 0) == (m < 0)); 582 int diff = SkAbs32(mod - SkFloatToFixed(m)); 583 REPORTER_ASSERT(reporter, (diff >> 7) == 0); 584 } 585 } 586 #endif 587 588 for (i = 0; i < 10000; i++) { 589 SkFract x = rand.nextU() >> 1; 590 double xx = (double)x / SK_Fract1; 591 SkFract xr = SkFractSqrt(x); 592 SkFract check = SkFloatToFract(sqrt(xx)); 593 REPORTER_ASSERT(reporter, xr == check || 594 xr == check-1 || 595 xr == check+1); 596 597 xr = SkFixedSqrt(x); 598 xx = (double)x / SK_Fixed1; 599 check = SkFloatToFixed(sqrt(xx)); 600 REPORTER_ASSERT(reporter, xr == check || xr == check-1); 601 602 xr = SkSqrt32(x); 603 xx = (double)x; 604 check = (int32_t)sqrt(xx); 605 REPORTER_ASSERT(reporter, xr == check || xr == check-1); 606 } 607 608 #if !defined(SK_SCALAR_IS_FLOAT) 609 { 610 SkFixed s, c; 611 s = SkFixedSinCos(0, &c); 612 REPORTER_ASSERT(reporter, s == 0); 613 REPORTER_ASSERT(reporter, c == SK_Fixed1); 614 } 615 616 int maxDiff = 0; 617 for (i = 0; i < 1000; i++) { 618 SkFixed rads = rand.nextS() >> 10; 619 double frads = SkFixedToFloat(rads); 620 621 SkFixed s, c; 622 s = SkScalarSinCos(rads, &c); 623 624 double fs = sin(frads); 625 double fc = cos(frads); 626 627 SkFixed is = SkFloatToFixed(fs); 628 SkFixed ic = SkFloatToFixed(fc); 629 630 maxDiff = SkMax32(maxDiff, SkAbs32(is - s)); 631 maxDiff = SkMax32(maxDiff, SkAbs32(ic - c)); 632 } 633 SkDebugf("SinCos: maximum error = %d\n", maxDiff); 634 #endif 635 636 #ifdef SK_SCALAR_IS_FLOAT 637 test_blend(reporter); 638 #endif 639 640 if (false) test_floor(reporter); 641 642 // disable for now 643 if (false) test_blend31(); // avoid bit rot, suppress warning 644 645 test_muldivround(reporter); 646 test_clz(reporter); 647 } 648 649 #include "TestClassDef.h" 650 DEFINE_TESTCLASS("Math", MathTestClass, TestMath) 651 652 /////////////////////////////////////////////////////////////////////////////// 653 654 #include "SkEndian.h" 655 656 template <typename T> struct PairRec { 657 T fYin; 658 T fYang; 659 }; 660 661 static void TestEndian(skiatest::Reporter* reporter) { 662 static const PairRec<uint16_t> g16[] = { 663 { 0x0, 0x0 }, 664 { 0xFFFF, 0xFFFF }, 665 { 0x1122, 0x2211 }, 666 }; 667 static const PairRec<uint32_t> g32[] = { 668 { 0x0, 0x0 }, 669 { 0xFFFFFFFF, 0xFFFFFFFF }, 670 { 0x11223344, 0x44332211 }, 671 }; 672 static const PairRec<uint64_t> g64[] = { 673 { 0x0, 0x0 }, 674 { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL }, 675 { 0x1122334455667788ULL, 0x8877665544332211ULL }, 676 }; 677 678 REPORTER_ASSERT(reporter, 0x1122 == SkTEndianSwap16<0x2211>::value); 679 REPORTER_ASSERT(reporter, 0x11223344 == SkTEndianSwap32<0x44332211>::value); 680 REPORTER_ASSERT(reporter, 0x1122334455667788ULL == SkTEndianSwap64<0x8877665544332211ULL>::value); 681 682 for (size_t i = 0; i < SK_ARRAY_COUNT(g16); ++i) { 683 REPORTER_ASSERT(reporter, g16[i].fYang == SkEndianSwap16(g16[i].fYin)); 684 } 685 for (size_t i = 0; i < SK_ARRAY_COUNT(g32); ++i) { 686 REPORTER_ASSERT(reporter, g32[i].fYang == SkEndianSwap32(g32[i].fYin)); 687 } 688 for (size_t i = 0; i < SK_ARRAY_COUNT(g64); ++i) { 689 REPORTER_ASSERT(reporter, g64[i].fYang == SkEndianSwap64(g64[i].fYin)); 690 } 691 } 692 693 DEFINE_TESTCLASS("Endian", EndianTestClass, TestEndian) 694