Flutter Engine
The Flutter Engine
Classes | Functions | Variables
MathTest.cpp File Reference
#include "include/core/SkPoint.h"
#include "include/core/SkScalar.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkFixed.h"
#include "include/private/base/SkFloatingPoint.h"
#include "include/private/base/SkMath.h"
#include "include/private/base/SkTPin.h"
#include "src/base/SkEndian.h"
#include "src/base/SkHalf.h"
#include "src/base/SkMathPriv.h"
#include "src/base/SkRandom.h"
#include "tests/Test.h"
#include <array>
#include <cinttypes>
#include <cmath>
#include <cstddef>
#include <cstdint>

Go to the source code of this file.

Classes

struct  PairRec< T >
 

Functions

static void test_clz (skiatest::Reporter *reporter)
 
static void test_ctz (skiatest::Reporter *reporter)
 
static float sk_fsel (float pred, float result_ge, float result_lt)
 
static float fast_floor (float x)
 
static float std_floor (float x)
 
static void test_floor_value (skiatest::Reporter *reporter, float value)
 
static void test_floor (skiatest::Reporter *reporter)
 
static float float_blend (int src, int dst, float unit)
 
static int blend31 (int src, int dst, int a31)
 
static int blend31_slow (int src, int dst, int a31)
 
static int blend31_round (int src, int dst, int a31)
 
static int blend31_old (int src, int dst, int a31)
 
static void test_blend31 ()
 
static void check_length (skiatest::Reporter *reporter, const SkPoint &p, SkScalar targetLen)
 
template<typename T >
static void unittest_isfinite (skiatest::Reporter *reporter)
 
static void unittest_half (skiatest::Reporter *reporter)
 
template<typename RSqrtFn >
static void test_rsqrt (skiatest::Reporter *reporter, RSqrtFn rsqrt)
 
static void test_muldiv255 (skiatest::Reporter *reporter)
 
static void test_muldiv255ceiling (skiatest::Reporter *reporter)
 
static void test_copysign (skiatest::Reporter *reporter)
 
static void huge_vector_normalize (skiatest::Reporter *reporter)
 
 DEF_TEST (PopCount, reporter)
 
 DEF_TEST (NthSet, reporter)
 
 DEF_TEST (Math, reporter)
 
 DEF_TEST (TestEndian, reporter)
 
template<typename T >
static void test_divmod (skiatest::Reporter *r)
 
 DEF_TEST (divmod_u8, r)
 
 DEF_TEST (divmod_u16, r)
 
 DEF_TEST (divmod_u32, r)
 
 DEF_TEST (divmod_u64, r)
 
 DEF_TEST (divmod_s8, r)
 
 DEF_TEST (divmod_s16, r)
 
 DEF_TEST (divmod_s32, r)
 
 DEF_TEST (divmod_s64, r)
 
static void test_nextsizepow2 (skiatest::Reporter *r, size_t test, size_t expectedAns)
 
 DEF_TEST (GrNextSizePow2, reporter)
 
 DEF_TEST (FloatSaturate32, reporter)
 
 DEF_TEST (FloatSaturate64, reporter)
 
 DEF_TEST (DoubleSaturate32, reporter)
 

Variables

static int(* blend_functions [])(int, int, int)
 

Function Documentation

◆ blend31()

static int blend31 ( int  src,
int  dst,
int  a31 
)
static

Definition at line 108 of file MathTest.cpp.

108 {
109 return dst + ((src - dst) * a31 * 2114 >> 16);
110 // return dst + ((src - dst) * a31 * 33 >> 10);
111}
dst
Definition: cp.py:12

◆ blend31_old()

static int blend31_old ( int  src,
int  dst,
int  a31 
)
static

Definition at line 125 of file MathTest.cpp.

125 {
126 a31 += a31 >> 4;
127 return dst + ((src - dst) * a31 >> 5);
128}

◆ blend31_round()

static int blend31_round ( int  src,
int  dst,
int  a31 
)
static

Definition at line 119 of file MathTest.cpp.

119 {
120 int prod = (src - dst) * a31 + 16;
121 prod = (prod + (prod >> 5)) >> 5;
122 return dst + prod;
123}

◆ blend31_slow()

static int blend31_slow ( int  src,
int  dst,
int  a31 
)
static

Definition at line 113 of file MathTest.cpp.

113 {
114 int prod = src * a31 + (31 - a31) * dst + 16;
115 prod = (prod + (prod >> 5)) >> 5;
116 return prod;
117}

◆ check_length()

static void check_length ( skiatest::Reporter reporter,
const SkPoint p,
SkScalar  targetLen 
)
static

Definition at line 172 of file MathTest.cpp.

173 {
174 float x = p.fX;
175 float y = p.fY;
176 float len = std::sqrt(x*x + y*y);
177
178 len /= targetLen;
179
180 REPORTER_ASSERT(reporter, len > 0.999f && len < 1.001f);
181}
reporter
Definition: FontMgrTest.cpp:39
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
double y
double x
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
Definition: SkVx.h:706

◆ DEF_TEST() [1/16]

DEF_TEST ( divmod_s16  ,
 
)

Definition at line 695 of file MathTest.cpp.

695 {
696 test_divmod<int16_t>(r);
697}

◆ DEF_TEST() [2/16]

DEF_TEST ( divmod_s32  ,
 
)

Definition at line 699 of file MathTest.cpp.

699 {
700 test_divmod<int32_t>(r);
701}

◆ DEF_TEST() [3/16]

DEF_TEST ( divmod_s64  ,
 
)

Definition at line 703 of file MathTest.cpp.

703 {
704 test_divmod<int64_t>(r);
705}

◆ DEF_TEST() [4/16]

DEF_TEST ( divmod_s8  ,
 
)

Definition at line 691 of file MathTest.cpp.

691 {
692 test_divmod<int8_t>(r);
693}

◆ DEF_TEST() [5/16]

DEF_TEST ( divmod_u16  ,
 
)

Definition at line 679 of file MathTest.cpp.

679 {
680 test_divmod<uint16_t>(r);
681}

◆ DEF_TEST() [6/16]

DEF_TEST ( divmod_u32  ,
 
)

Definition at line 683 of file MathTest.cpp.

683 {
684 test_divmod<uint32_t>(r);
685}

◆ DEF_TEST() [7/16]

DEF_TEST ( divmod_u64  ,
 
)

Definition at line 687 of file MathTest.cpp.

687 {
688 test_divmod<uint64_t>(r);
689}

◆ DEF_TEST() [8/16]

DEF_TEST ( divmod_u8  ,
 
)

Definition at line 675 of file MathTest.cpp.

675 {
676 test_divmod<uint8_t>(r);
677}

◆ DEF_TEST() [9/16]

DEF_TEST ( DoubleSaturate32  ,
reporter   
)

Definition at line 793 of file MathTest.cpp.

793 {
794 const struct {
795 double fDouble;
796 int fExpectedInt;
797 } recs[] = {
798 { 0, 0 },
799 { 100.5, 100 },
800 { SK_MaxS32, SK_MaxS32 },
801 { SK_MinS32, SK_MinS32 },
802 { SK_MaxS32 - 1, SK_MaxS32 - 1 },
803 { SK_MinS32 + 1, SK_MinS32 + 1 },
804 { SK_MaxS32 * 100.0, SK_MaxS32 },
805 { SK_MinS32 * 100.0, SK_MinS32 },
809 };
810
811 for (auto r : recs) {
812 int i = sk_double_saturate2int(r.fDouble);
813 REPORTER_ASSERT(reporter, r.fExpectedInt == i);
814 }
815}
static constexpr int sk_double_saturate2int(double x)
static constexpr int32_t SK_MinS32
Definition: SkMath.h:22
static constexpr int32_t SK_MaxS32
Definition: SkMath.h:21
#define SK_ScalarNaN
Definition: SkScalar.h:28
#define SK_ScalarInfinity
Definition: SkScalar.h:26
#define SK_ScalarNegativeInfinity
Definition: SkScalar.h:27

◆ DEF_TEST() [10/16]

DEF_TEST ( FloatSaturate32  ,
reporter   
)

Definition at line 745 of file MathTest.cpp.

745 {
746 const struct {
747 float fFloat;
748 int fExpectedInt;
749 } recs[] = {
750 { 0, 0 },
751 { 100.5f, 100 },
754 { SK_MaxS32 * 100.0f, SK_MaxS32FitsInFloat },
755 { SK_MinS32 * 100.0f, SK_MinS32FitsInFloat },
759 };
760
761 for (auto r : recs) {
762 int i = sk_float_saturate2int(r.fFloat);
763 REPORTER_ASSERT(reporter, r.fExpectedInt == i);
764
765 // Ensure that SkTPin bounds even non-finite values (including NaN)
766 SkScalar p = SkTPin<SkScalar>(r.fFloat, 0, 100);
767 REPORTER_ASSERT(reporter, p >= 0 && p <= 100);
768 }
769}
constexpr int SK_MinS32FitsInFloat
constexpr int SK_MaxS32FitsInFloat
static constexpr int sk_float_saturate2int(float x)
float SkScalar
Definition: extension.cpp:12

◆ DEF_TEST() [11/16]

DEF_TEST ( FloatSaturate64  ,
reporter   
)

Definition at line 771 of file MathTest.cpp.

771 {
772 const struct {
773 float fFloat;
774 int64_t fExpected64;
775 } recs[] = {
776 { 0, 0 },
777 { 100.5f, 100 },
780 { SK_MaxS64 * 100.0f, SK_MaxS64FitsInFloat },
781 { SK_MinS64 * 100.0f, SK_MinS64FitsInFloat },
785 };
786
787 for (auto r : recs) {
788 int64_t i = sk_float_saturate2int64(r.fFloat);
789 REPORTER_ASSERT(reporter, r.fExpected64 == i);
790 }
791}
constexpr int64_t SK_MinS64FitsInFloat
static constexpr int64_t sk_float_saturate2int64(float x)
constexpr int64_t SK_MaxS64FitsInFloat
static constexpr int64_t SK_MaxS64
Definition: SkMath.h:25
static constexpr int64_t SK_MinS64
Definition: SkMath.h:26

◆ DEF_TEST() [12/16]

DEF_TEST ( GrNextSizePow2  ,
reporter   
)

Definition at line 714 of file MathTest.cpp.

714 {
715 constexpr int kNumSizeTBits = 8 * sizeof(size_t);
716
717 size_t test = 0, expectedAns = 1;
718
719 test_nextsizepow2(reporter, test, expectedAns);
720
721 test = 1; expectedAns = 1;
722
723 for (int i = 1; i < kNumSizeTBits; ++i) {
724 test_nextsizepow2(reporter, test, expectedAns);
725
726 test++;
727 expectedAns <<= 1;
728
729 test_nextsizepow2(reporter, test, expectedAns);
730
731 test = expectedAns;
732 }
733
734 // For the remaining three tests there is no higher power (of 2)
735 test = 0x1;
736 test <<= kNumSizeTBits-1;
738
739 test++;
741
742 test_nextsizepow2(reporter, SIZE_MAX, SIZE_MAX);
743}
static void test_nextsizepow2(skiatest::Reporter *r, size_t test, size_t expectedAns)
Definition: MathTest.cpp:707

◆ DEF_TEST() [13/16]

DEF_TEST ( Math  ,
reporter   
)

Definition at line 496 of file MathTest.cpp.

496 {
497 int i;
498 SkRandom rand;
499
500 // these should assert
501#if 0
502 SkToS8(128);
503 SkToS8(-129);
504 SkToU8(256);
505 SkToU8(-5);
506
507 SkToS16(32768);
508 SkToS16(-32769);
509 SkToU16(65536);
510 SkToU16(-5);
511
512 if (sizeof(size_t) > 4) {
513 SkToS32(4*1024*1024);
514 SkToS32(-4*1024*1024);
515 SkToU32(5*1024*1024);
516 SkToU32(-5);
517 }
518#endif
519
523
524 {
527 }
528
529 for (i = 0; i < 10000; i++) {
530 SkPoint p;
531
532 // These random values are being treated as 32-bit-patterns, not as
533 // ints; calling SkIntToScalar() here produces crashes.
534 p.setLength((SkScalar) rand.nextS(),
535 (SkScalar) rand.nextS(),
536 SK_Scalar1);
538 p.setLength((SkScalar) (rand.nextS() >> 13),
539 (SkScalar) (rand.nextS() >> 13),
540 SK_Scalar1);
542 }
543
544 {
545 SkFixed result = SkFixedDiv(100, 100);
549 result = SkFixedDiv(10 - 1, SK_Fixed1 * 3);
551 }
552
553 {
557 }
558
560 unittest_isfinite<float>(reporter);
561 unittest_isfinite<double>(reporter);
565
566 for (i = 0; i < 10000; i++) {
567 SkFixed numer = rand.nextS();
568 SkFixed denom = rand.nextS();
569 SkFixed result = SkFixedDiv(numer, denom);
570 int64_t check = SkLeftShift((int64_t)numer, 16) / denom;
571
572 (void)SkCLZ(numer);
573 (void)SkCLZ(denom);
574
576 if (check > SK_MaxS32) {
578 } else if (check < -SK_MaxS32) {
580 }
581 if (result != (int32_t)check) {
582 ERRORF(reporter, "\nFixed Divide: %8x / %8x -> %8x %8" PRIx64 "\n",
583 (uint32_t)numer, (uint32_t)denom, (uint32_t)result, (uint64_t)check);
584 }
585 REPORTER_ASSERT(reporter, result == (int32_t)check);
586 }
587
588 if ((false)) test_floor(reporter);
589
590 // disable for now
591 if ((false)) test_blend31(); // avoid bit rot, suppress warning
592
595}
static void test_copysign(skiatest::Reporter *reporter)
Definition: MathTest.cpp:346
static void test_muldiv255ceiling(skiatest::Reporter *reporter)
Definition: MathTest.cpp:333
static void huge_vector_normalize(skiatest::Reporter *reporter)
Definition: MathTest.cpp:384
static void check_length(skiatest::Reporter *reporter, const SkPoint &p, SkScalar targetLen)
Definition: MathTest.cpp:172
static void test_blend31()
Definition: MathTest.cpp:138
static void test_floor(skiatest::Reporter *reporter)
Definition: MathTest.cpp:91
static void test_clz(skiatest::Reporter *reporter)
Definition: MathTest.cpp:28
static void test_ctz(skiatest::Reporter *reporter)
Definition: MathTest.cpp:47
static void test_muldiv255(skiatest::Reporter *reporter)
Definition: MathTest.cpp:312
static void test_rsqrt(skiatest::Reporter *reporter, RSqrtFn rsqrt)
Definition: MathTest.cpp:278
static void unittest_half(skiatest::Reporter *reporter)
Definition: MathTest.cpp:222
#define check(reporter, ref, unref, make, kill)
Definition: RefCntTest.cpp:85
int32_t SkFixed
Definition: SkFixed.h:25
#define SK_Fixed1
Definition: SkFixed.h:26
static SkFixed SkFixedCeilToFixed(SkFixed x)
Definition: SkFixed.h:83
#define SkFixedDiv(numer, denom)
Definition: SkFixed.h:93
static SkFixed SkFixedFloorToFixed(SkFixed x)
Definition: SkFixed.h:86
static SkFixed SkFixedRoundToFixed(SkFixed x)
Definition: SkFixed.h:80
static constexpr bool SkIsNaN(T x)
static float sk_float_rsqrt_portable(float x)
static float sk_float_rsqrt(float x)
static int SkCLZ(uint32_t mask)
Definition: SkMathPriv.h:186
static constexpr int32_t SkLeftShift(int32_t value, int32_t shift)
Definition: SkMath.h:37
static constexpr int32_t SK_NaN32
Definition: SkMath.h:23
#define SK_Scalar1
Definition: SkScalar.h:18
constexpr int8_t SkToS8(S x)
Definition: SkTo.h:21
constexpr uint16_t SkToU16(S x)
Definition: SkTo.h:24
constexpr int32_t SkToS32(S x)
Definition: SkTo.h:25
constexpr uint8_t SkToU8(S x)
Definition: SkTo.h:22
constexpr int16_t SkToS16(S x)
Definition: SkTo.h:23
constexpr uint32_t SkToU32(S x)
Definition: SkTo.h:26
#define ERRORF(r,...)
Definition: Test.h:293
int32_t nextS()
Definition: SkRandom.h:50
GAsyncResult * result

◆ DEF_TEST() [14/16]

DEF_TEST ( NthSet  ,
reporter   
)

Definition at line 439 of file MathTest.cpp.

439 {
440 {
441 uint32_t testVal = 0x1;
442 uint32_t recreated = 0;
443 int result = SkNthSet(testVal, 0);
444 recreated |= (0x1 << result);
445 REPORTER_ASSERT(reporter, testVal == recreated);
446 }
447
448 {
449 uint32_t testVal = 0x80000000;
450 uint32_t recreated = 0;
451 int result = SkNthSet(testVal, 0);
452 recreated |= (0x1 << result);
453 REPORTER_ASSERT(reporter, testVal == recreated);
454 }
455
456 {
457 uint32_t testVal = 0x55555555;
458 uint32_t recreated = 0;
459 for (int i = 0; i < 16; ++i) {
460 int result = SkNthSet(testVal, i);
462 recreated |= (0x1 << result);
463 }
464 REPORTER_ASSERT(reporter, testVal == recreated);
465 }
466
467 SkRandom rand;
468 for (int i = 0; i < 100; ++i) {
469 int expectedNumSetBits = 0;
470 uint32_t testVal = 0;
471
472 int numTries = rand.nextULessThan(33);
473 for (int j = 0; j < numTries; ++j) {
474 int bit = rand.nextRangeU(0, 31);
475
476 if (testVal & (0x1 << bit)) {
477 continue;
478 }
479
480 ++expectedNumSetBits;
481 testVal |= 0x1 << bit;
482 }
483
484 REPORTER_ASSERT(reporter, SkPopCount(testVal) == expectedNumSetBits);
485 uint32_t recreated = 0;
486
487 for (int j = 0; j < expectedNumSetBits; ++j) {
488 int index = SkNthSet(testVal, j);
489 recreated |= (0x1 << index);
490 }
491
492 REPORTER_ASSERT(reporter, recreated == testVal);
493 }
494}
int SkNthSet(uint32_t target, int n)
Definition: SkMathPriv.cpp:53
static int SkPopCount(uint32_t n)
Definition: SkMathPriv.h:136
uint32_t nextULessThan(uint32_t count)
Definition: SkRandom.h:93
uint32_t nextRangeU(uint32_t min, uint32_t max)
Definition: SkRandom.h:80

◆ DEF_TEST() [15/16]

DEF_TEST ( PopCount  ,
reporter   
)

Definition at line 399 of file MathTest.cpp.

399 {
400 {
401 uint32_t testVal = 0;
402 REPORTER_ASSERT(reporter, SkPopCount(testVal) == 0);
403 }
404
405 for (int i = 0; i < 32; ++i) {
406 uint32_t testVal = 0x1 << i;
407 REPORTER_ASSERT(reporter, SkPopCount(testVal) == 1);
408
409 testVal ^= 0xFFFFFFFF;
410 REPORTER_ASSERT(reporter, SkPopCount(testVal) == 31);
411 }
412
413 {
414 uint32_t testVal = 0xFFFFFFFF;
415 REPORTER_ASSERT(reporter, SkPopCount(testVal) == 32);
416 }
417
418 SkRandom rand;
419 for (int i = 0; i < 100; ++i) {
420 int expectedNumSetBits = 0;
421 uint32_t testVal = 0;
422
423 int numTries = rand.nextULessThan(33);
424 for (int j = 0; j < numTries; ++j) {
425 int bit = rand.nextRangeU(0, 31);
426
427 if (testVal & (0x1 << bit)) {
428 continue;
429 }
430
431 ++expectedNumSetBits;
432 testVal |= 0x1 << bit;
433 }
434
435 REPORTER_ASSERT(reporter, SkPopCount(testVal) == expectedNumSetBits);
436 }
437}

◆ DEF_TEST() [16/16]

DEF_TEST ( TestEndian  ,
reporter   
)

Definition at line 602 of file MathTest.cpp.

602 {
603 static const PairRec<uint16_t> g16[] = {
604 { 0x0, 0x0 },
605 { 0xFFFF, 0xFFFF },
606 { 0x1122, 0x2211 },
607 };
608 static const PairRec<uint32_t> g32[] = {
609 { 0x0, 0x0 },
610 { 0xFFFFFFFF, 0xFFFFFFFF },
611 { 0x11223344, 0x44332211 },
612 };
613 static const PairRec<uint64_t> g64[] = {
614 { 0x0, 0x0 },
615 { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL },
616 { 0x1122334455667788ULL, 0x8877665544332211ULL },
617 };
618
622
623 for (size_t i = 0; i < std::size(g16); ++i) {
624 REPORTER_ASSERT(reporter, g16[i].fYang == SkEndianSwap16(g16[i].fYin));
625 }
626 for (size_t i = 0; i < std::size(g32); ++i) {
627 REPORTER_ASSERT(reporter, g32[i].fYang == SkEndianSwap32(g32[i].fYin));
628 }
629 for (size_t i = 0; i < std::size(g64); ++i) {
630 REPORTER_ASSERT(reporter, g64[i].fYang == SkEndianSwap64(g64[i].fYin));
631 }
632}
static uint64_t SkEndianSwap64(uint64_t value)
Definition: SkEndian.h:85
static uint16_t SkEndianSwap16(uint16_t value)
Definition: SkEndian.h:33
static constexpr uint32_t SkEndianSwap32(uint32_t value)
Definition: SkEndian.h:56
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259

◆ fast_floor()

static float fast_floor ( float  x)
static

Definition at line 72 of file MathTest.cpp.

72 {
73// float big = sk_fsel(x, 0x1.0p+23, -0x1.0p+23);
74 float big = sk_fsel(x, (float)(1 << 23), -(float)(1 << 23));
75 return (float)(x + big) - big;
76}
static float sk_fsel(float pred, float result_ge, float result_lt)
Definition: MathTest.cpp:68

◆ float_blend()

static float float_blend ( int  src,
int  dst,
float  unit 
)
static

Definition at line 104 of file MathTest.cpp.

104 {
105 return dst + (src - dst) * unit;
106}

◆ huge_vector_normalize()

static void huge_vector_normalize ( skiatest::Reporter reporter)
static

Definition at line 384 of file MathTest.cpp.

384 {
385 // these values should fail (overflow/underflow) trying to normalize
386 const SkVector fail[] = {
387 { 0, 0 },
389 { 0, SK_ScalarNaN }, { SK_ScalarNaN, 0 },
390 };
391 for (SkVector v : fail) {
392 SkVector v2 = v;
393 if (v2.setLength(1.0f)) {
394 REPORTER_ASSERT(reporter, !v.setLength(1.0f));
395 }
396 }
397}
static void fail(const SkString &err)
Definition: DM.cpp:234
Vec2Value v2

◆ sk_fsel()

static float sk_fsel ( float  pred,
float  result_ge,
float  result_lt 
)
static

Definition at line 68 of file MathTest.cpp.

68 {
69 return pred >= 0 ? result_ge : result_lt;
70}

◆ std_floor()

static float std_floor ( float  x)
static

Definition at line 78 of file MathTest.cpp.

78 {
79 return std::floor(x);
80}
SIN Vec< N, float > floor(const Vec< N, float > &x)
Definition: SkVx.h:703

◆ test_blend31()

static void test_blend31 ( )
static

Definition at line 138 of file MathTest.cpp.

138 {
139 int failed = 0;
140 int death = 0;
141 if ((false)) { // avoid bit rot, suppress warning
142 failed = (*blend_functions[0])(0,0,0);
143 }
144 for (int src = 0; src <= 255; src++) {
145 for (int dst = 0; dst <= 255; dst++) {
146 for (int a = 0; a <= 31; a++) {
147// int r0 = blend31(src, dst, a);
148// int r0 = blend31_round(src, dst, a);
149// int r0 = blend31_old(src, dst, a);
150 int r0 = blend31_slow(src, dst, a);
151
152 float f = float_blend(src, dst, a / 31.f);
153 int r1 = (int)f;
154 int r2 = SkScalarRoundToInt(f);
155
156 if (r0 != r1 && r0 != r2) {
157 SkDebugf("src:%d dst:%d a:%d result:%d float:%g\n",
158 src, dst, a, r0, f);
159 failed += 1;
160 }
161 if (r0 > 255) {
162 death += 1;
163 SkDebugf("death src:%d dst:%d a:%d result:%d float:%g\n",
164 src, dst, a, r0, f);
165 }
166 }
167 }
168 }
169 SkDebugf("---- failed %d death %d\n", failed, death);
170}
static float float_blend(int src, int dst, float unit)
Definition: MathTest.cpp:104
static int blend31_slow(int src, int dst, int a31)
Definition: MathTest.cpp:113
static int(* blend_functions[])(int, int, int)
Definition: MathTest.cpp:131
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
#define SkScalarRoundToInt(x)
Definition: SkScalar.h:37
struct MyStruct a[10]

◆ test_clz()

static void test_clz ( skiatest::Reporter reporter)
static

Definition at line 28 of file MathTest.cpp.

28 {
31 REPORTER_ASSERT(reporter, 1 == SkCLZ(1 << 30));
32 REPORTER_ASSERT(reporter, 1 == SkCLZ((1 << 30) | (1 << 24) | 1));
34
35 SkRandom rand;
36 for (int i = 0; i < 1000; ++i) {
37 uint32_t mask = rand.nextU();
38 // need to get some zeros for testing, but in some obscure way so the
39 // compiler won't "see" that, and work-around calling the functions.
40 mask >>= (mask & 31);
41 int intri = SkCLZ(mask);
42 int porta = SkCLZ_portable(mask);
43 REPORTER_ASSERT(reporter, intri == porta, "mask:%u intri:%d porta:%d", mask, intri, porta);
44 }
45}
constexpr int SkCLZ_portable(uint32_t x)
Returns the number of leading zero bits (0...32)
Definition: SkMathPriv.h:149
uint32_t nextU()
Definition: SkRandom.h:42

◆ test_copysign()

static void test_copysign ( skiatest::Reporter reporter)
static

Definition at line 346 of file MathTest.cpp.

346 {
347 static const int32_t gTriples[] = {
348 // x, y, expected result
349 0, 0, 0,
350 0, 1, 0,
351 0, -1, 0,
352 1, 0, 1,
353 1, 1, 1,
354 1, -1, -1,
355 -1, 0, 1,
356 -1, 1, 1,
357 -1, -1, -1,
358 };
359 for (size_t i = 0; i < std::size(gTriples); i += 3) {
361 SkCopySign32(gTriples[i], gTriples[i+1]) == gTriples[i+2]);
362 float x = (float)gTriples[i];
363 float y = (float)gTriples[i+1];
364 float expected = (float)gTriples[i+2];
365 REPORTER_ASSERT(reporter, std::copysign(x, y) == expected);
366 }
367
368 SkRandom rand;
369 for (int j = 0; j < 1000; j++) {
370 int ix = rand.nextS();
371 REPORTER_ASSERT(reporter, SkCopySign32(ix, ix) == ix);
372 REPORTER_ASSERT(reporter, SkCopySign32(ix, -ix) == -ix);
373 REPORTER_ASSERT(reporter, SkCopySign32(-ix, ix) == ix);
374 REPORTER_ASSERT(reporter, SkCopySign32(-ix, -ix) == -ix);
375
376 SkScalar sx = rand.nextSScalar1();
378 REPORTER_ASSERT(reporter, SkScalarCopySign(sx, -sx) == -sx);
380 REPORTER_ASSERT(reporter, SkScalarCopySign(-sx, -sx) == -sx);
381 }
382}
static int32_t SkCopySign32(int32_t x, int32_t y)
Definition: SkMathPriv.h:56
#define SkScalarCopySign(x, y)
Definition: SkScalar.h:40
SkScalar nextSScalar1()
Definition: SkRandom.h:113

◆ test_ctz()

static void test_ctz ( skiatest::Reporter reporter)
static

Definition at line 47 of file MathTest.cpp.

47 {
50 REPORTER_ASSERT(reporter, 30 == SkCTZ(1 << 30));
51 REPORTER_ASSERT(reporter, 2 == SkCTZ((1 << 30) | (1 << 24) | (1 << 2)));
53
54 SkRandom rand;
55 for (int i = 0; i < 1000; ++i) {
56 uint32_t mask = rand.nextU();
57 // need to get some zeros for testing, but in some obscure way so the
58 // compiler won't "see" that, and work-around calling the functions.
59 mask >>= (mask & 31);
60 int intri = SkCTZ(mask);
61 int porta = SkCTZ_portable(mask);
62 REPORTER_ASSERT(reporter, intri == porta, "mask:%u intri:%d porta:%d", mask, intri, porta);
63 }
64}
constexpr int SkCTZ_portable(uint32_t x)
Returns the number of trailing zero bits (0...32)
Definition: SkMathPriv.h:193
static int SkCTZ(uint32_t mask)
Definition: SkMathPriv.h:224

◆ test_divmod()

template<typename T >
static void test_divmod ( skiatest::Reporter r)
static

Definition at line 635 of file MathTest.cpp.

635 {
636#if !defined(__MSVC_RUNTIME_CHECKS)
637 const struct {
638 T numer;
639 T denom;
640 } kEdgeCases[] = {
641 {(T)17, (T)17},
642 {(T)17, (T)4},
643 {(T)0, (T)17},
644 // For unsigned T these negatives are just some large numbers. Doesn't hurt to test them.
645 {(T)-17, (T)-17},
646 {(T)-17, (T)4},
647 {(T)17, (T)-4},
648 {(T)-17, (T)-4},
649 };
650
651 for (size_t i = 0; i < std::size(kEdgeCases); i++) {
652 const T numer = kEdgeCases[i].numer;
653 const T denom = kEdgeCases[i].denom;
654 T div, mod;
655 SkTDivMod(numer, denom, &div, &mod);
656 REPORTER_ASSERT(r, numer/denom == div);
657 REPORTER_ASSERT(r, numer%denom == mod);
658 }
659
660 SkRandom rand;
661 for (size_t i = 0; i < 10000; i++) {
662 const T numer = (T)rand.nextS();
663 T denom = 0;
664 while (0 == denom) {
665 denom = (T)rand.nextS();
666 }
667 T div, mod;
668 SkTDivMod(numer, denom, &div, &mod);
669 REPORTER_ASSERT(r, numer/denom == div);
670 REPORTER_ASSERT(r, numer%denom == mod);
671 }
672#endif
673}
void SkTDivMod(In numer, In denom, Out *div, Out *mod)
Definition: SkMathPriv.h:38
#define T
Definition: precompiler.cc:65

◆ test_floor()

static void test_floor ( skiatest::Reporter reporter)
static

Definition at line 91 of file MathTest.cpp.

91 {
92 static const float gVals[] = {
93 0, 1, 1.1f, 1.01f, 1.001f, 1.0001f, 1.00001f, 1.000001f, 1.0000001f
94 };
95
96 for (size_t i = 0; i < std::size(gVals); ++i) {
98// test_floor_value(reporter, -gVals[i]);
99 }
100}
static void test_floor_value(skiatest::Reporter *reporter, float value)
Definition: MathTest.cpp:82

◆ test_floor_value()

static void test_floor_value ( skiatest::Reporter reporter,
float  value 
)
static

Definition at line 82 of file MathTest.cpp.

82 {
83 float fast = fast_floor(value);
84 float std = std_floor(value);
85 if (std != fast) {
86 ERRORF(reporter, "fast_floor(%.9g) == %.9g != %.9g == std_floor(%.9g)",
87 value, fast, std, value);
88 }
89}
static float fast_floor(float x)
Definition: MathTest.cpp:72
static float std_floor(float x)
Definition: MathTest.cpp:78
uint8_t value
Definition: ref_ptr.h:256

◆ test_muldiv255()

static void test_muldiv255 ( skiatest::Reporter reporter)
static

Definition at line 312 of file MathTest.cpp.

312 {
313 for (int a = 0; a <= 255; a++) {
314 for (int b = 0; b <= 255; b++) {
315 int ab = a * b;
316 float s = ab / 255.0f;
317 int round = (int)floorf(s + 0.5f);
318 int trunc = (int)floorf(s);
319
320 int iround = SkMulDiv255Round(a, b);
321 int itrunc = SkMulDiv255Trunc(a, b);
322
324 REPORTER_ASSERT(reporter, itrunc == trunc);
325
326 REPORTER_ASSERT(reporter, itrunc <= iround);
329 }
330 }
331}
static void round(SkPoint *p)
static U8CPU SkMulDiv255Trunc(U8CPU a, U8CPU b)
Definition: SkMathPriv.h:92
static U8CPU SkMulDiv255Round(U16CPU a, U16CPU b)
Definition: SkMath.h:73
static bool b
struct MyStruct s
SI I32 iround(F v)
Definition: ab.py:1
SIN Vec< N, float > trunc(const Vec< N, float > &x)
Definition: SkVx.h:704

◆ test_muldiv255ceiling()

static void test_muldiv255ceiling ( skiatest::Reporter reporter)
static

Definition at line 333 of file MathTest.cpp.

333 {
334 for (int c = 0; c <= 255; c++) {
335 for (int a = 0; a <= 255; a++) {
336 int product = (c * a + 255);
337 int expected_ceiling = (product + (product >> 8)) >> 8;
338 int webkit_ceiling = (c * a + 254) / 255;
339 REPORTER_ASSERT(reporter, expected_ceiling == webkit_ceiling);
340 int skia_ceiling = SkMulDiv255Ceiling(c, a);
341 REPORTER_ASSERT(reporter, skia_ceiling == webkit_ceiling);
342 }
343 }
344}
static U8CPU SkMulDiv255Ceiling(U8CPU a, U8CPU b)
Definition: SkMathPriv.h:102

◆ test_nextsizepow2()

static void test_nextsizepow2 ( skiatest::Reporter r,
size_t  test,
size_t  expectedAns 
)
static

Definition at line 707 of file MathTest.cpp.

707 {
708 size_t ans = GrNextSizePow2(test);
709
710 REPORTER_ASSERT(r, ans == expectedAns);
711 //SkDebugf("0x%zx -> 0x%zx (0x%zx)\n", test, ans, expectedAns);
712}
static size_t GrNextSizePow2(size_t n)
Definition: SkMathPriv.h:309

◆ test_rsqrt()

template<typename RSqrtFn >
static void test_rsqrt ( skiatest::Reporter reporter,
RSqrtFn  rsqrt 
)
static

Definition at line 278 of file MathTest.cpp.

278 {
279 const float maxRelativeError = 6.50196699e-4f;
280
281 // test close to 0 up to 1
282 float input = 0.000001f;
283 for (int i = 0; i < 1000; ++i) {
284 float exact = 1.0f/std::sqrt(input);
285 float estimate = rsqrt(input);
286 float relativeError = std::fabs(exact - estimate)/exact;
287 REPORTER_ASSERT(reporter, relativeError <= maxRelativeError);
288 input += 0.001f;
289 }
290
291 // test 1 to ~100
292 input = 1.0f;
293 for (int i = 0; i < 1000; ++i) {
294 float exact = 1.0f/std::sqrt(input);
295 float estimate = rsqrt(input);
296 float relativeError = std::fabs(exact - estimate)/exact;
297 REPORTER_ASSERT(reporter, relativeError <= maxRelativeError);
298 input += 0.01f;
299 }
300
301 // test some big numbers
302 input = 1000000.0f;
303 for (int i = 0; i < 100; ++i) {
304 float exact = 1.0f/std::sqrt(input);
305 float estimate = rsqrt(input);
306 float relativeError = std::fabs(exact - estimate)/exact;
307 REPORTER_ASSERT(reporter, relativeError <= maxRelativeError);
308 input += 754326.f;
309 }
310}

◆ unittest_half()

static void unittest_half ( skiatest::Reporter reporter)
static

Definition at line 222 of file MathTest.cpp.

222 {
223 static const float gFloats[] = {
224 0.f, 1.f, 0.5f, 0.499999f, 0.5000001f, 1.f/3,
225 -0.f, -1.f, -0.5f, -0.499999f, -0.5000001f, -1.f/3
226 };
227
228 for (size_t i = 0; i < std::size(gFloats); ++i) {
229 SkHalf h = SkFloatToHalf(gFloats[i]);
230 float f = SkHalfToFloat(h);
232 }
233
234 // check some special values
235 union FloatUnion {
236 uint32_t fU;
237 float fF;
238 };
239
240 static const FloatUnion largestPositiveHalf = { ((142 << 23) | (1023 << 13)) };
241 SkHalf h = SkFloatToHalf(largestPositiveHalf.fF);
242 float f = SkHalfToFloat(h);
243 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(f, largestPositiveHalf.fF));
244
245 static const FloatUnion largestNegativeHalf = { (1u << 31) | (142u << 23) | (1023u << 13) };
246 h = SkFloatToHalf(largestNegativeHalf.fF);
247 f = SkHalfToFloat(h);
248 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(f, largestNegativeHalf.fF));
249
250 static const FloatUnion smallestPositiveHalf = { 102 << 23 };
251 h = SkFloatToHalf(smallestPositiveHalf.fF);
252 f = SkHalfToFloat(h);
253 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(f, smallestPositiveHalf.fF));
254
255 static const FloatUnion overflowHalf = { ((143 << 23) | (1023 << 13)) };
256 h = SkFloatToHalf(overflowHalf.fF);
257 f = SkHalfToFloat(h);
259
260 static const FloatUnion underflowHalf = { 101 << 23 };
261 h = SkFloatToHalf(underflowHalf.fF);
262 f = SkHalfToFloat(h);
263 REPORTER_ASSERT(reporter, f == 0.0f );
264
265 static const FloatUnion inf32 = { 255 << 23 };
266 h = SkFloatToHalf(inf32.fF);
267 f = SkHalfToFloat(h);
269
270 static const FloatUnion nan32 = { 255 << 23 | 1 };
271 h = SkFloatToHalf(nan32.fF);
272 f = SkHalfToFloat(h);
274
275}
static bool SkIsFinite(T x, Pack... values)
float SkHalfToFloat(SkHalf h)
Definition: SkHalf.cpp:24
SkHalf SkFloatToHalf(float f)
Definition: SkHalf.cpp:16
uint16_t SkHalf
Definition: SkHalf.h:16
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition: SkScalar.h:107
SkScalar h

◆ unittest_isfinite()

template<typename T >
static void unittest_isfinite ( skiatest::Reporter reporter)
static

Definition at line 184 of file MathTest.cpp.

184 {
185 const T zero = T(0);
186 const T plain = T(123);
187 const T inf = std::numeric_limits<T>::infinity();
188 const T big = std::numeric_limits<T>::max();
189 const T nan = inf * zero;
190
195
200
205
206 // SkIsFinite supports testing multiple values at once.
207 REPORTER_ASSERT(reporter, !SkIsFinite(inf, plain));
208 REPORTER_ASSERT(reporter, !SkIsFinite(plain, -inf));
209 REPORTER_ASSERT(reporter, !SkIsFinite(nan, plain));
210 REPORTER_ASSERT(reporter, SkIsFinite(plain, big));
211 REPORTER_ASSERT(reporter, SkIsFinite(-big, plain));
212 REPORTER_ASSERT(reporter, SkIsFinite(plain, zero));
213
214 REPORTER_ASSERT(reporter, !SkIsFinite(inf, plain, plain));
215 REPORTER_ASSERT(reporter, !SkIsFinite(plain, -inf, plain));
216 REPORTER_ASSERT(reporter, !SkIsFinite(plain, plain, nan));
217 REPORTER_ASSERT(reporter, SkIsFinite(big, plain, plain));
218 REPORTER_ASSERT(reporter, SkIsFinite(plain, -big, plain));
219 REPORTER_ASSERT(reporter, SkIsFinite(plain, plain, zero));
220}
static float max(float r, float g, float b)
Definition: hsl.cpp:49

Variable Documentation

◆ blend_functions

int(* blend_functions[])(int, int, int) ( int  ,
int  ,
int   
)
static
Initial value:
= {
}
static int blend31_old(int src, int dst, int a31)
Definition: MathTest.cpp:125
static int blend31(int src, int dst, int a31)
Definition: MathTest.cpp:108
static int blend31_round(int src, int dst, int a31)
Definition: MathTest.cpp:119

Definition at line 131 of file MathTest.cpp.