36 for (
int i = 0; i < 1000; ++i) {
37 uint32_t mask = rand.
nextU();
41 int intri =
SkCLZ(mask);
55 for (
int i = 0; i < 1000; ++i) {
56 uint32_t mask = rand.
nextU();
60 int intri =
SkCTZ(mask);
68static float sk_fsel(
float pred,
float result_ge,
float result_lt) {
69 return pred >= 0 ? result_ge : result_lt;
74 float big =
sk_fsel(
x, (
float)(1 << 23), -(
float)(1 << 23));
75 return (
float)(
x + big) - big;
86 ERRORF(
reporter,
"fast_floor(%.9g) == %.9g != %.9g == std_floor(%.9g)",
92 static const float gVals[] = {
93 0, 1, 1.1f, 1.01f, 1.001f, 1.0001f, 1.00001f, 1.000001f, 1.0000001f
96 for (
size_t i = 0; i < std::size(gVals); ++i) {
105 return dst + (src - dst) * unit;
108static int blend31(
int src,
int dst,
int a31) {
109 return dst + ((src - dst) * a31 * 2114 >> 16);
114 int prod = src * a31 + (31 - a31) * dst + 16;
115 prod = (prod + (prod >> 5)) >> 5;
120 int prod = (src - dst) * a31 + 16;
121 prod = (prod + (prod >> 5)) >> 5;
127 return dst + ((src - dst) * a31 >> 5);
144 for (
int src = 0; src <= 255; src++) {
145 for (
int dst = 0; dst <= 255; dst++) {
146 for (
int a = 0;
a <= 31;
a++) {
156 if (r0 != r1 && r0 != r2) {
157 SkDebugf(
"src:%d dst:%d a:%d result:%d float:%g\n",
163 SkDebugf(
"death src:%d dst:%d a:%d result:%d float:%g\n",
169 SkDebugf(
"---- failed %d death %d\n", failed, death);
176 float len = std::sqrt(
x*
x +
y*
y);
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;
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
228 for (
size_t i = 0; i < std::size(gFloats); ++i) {
240 static const FloatUnion largestPositiveHalf = { ((142 << 23) | (1023 << 13)) };
245 static const FloatUnion largestNegativeHalf = { (1u << 31) | (142u << 23) | (1023u << 13) };
250 static const FloatUnion smallestPositiveHalf = { 102 << 23 };
255 static const FloatUnion overflowHalf = { ((143 << 23) | (1023 << 13)) };
260 static const FloatUnion underflowHalf = { 101 << 23 };
265 static const FloatUnion inf32 = { 255 << 23 };
270 static const FloatUnion nan32 = { 255 << 23 | 1 };
277template <
typename RSqrtFn>
279 const float maxRelativeError = 6.50196699e-4f;
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;
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;
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;
313 for (
int a = 0;
a <= 255;
a++) {
314 for (
int b = 0;
b <= 255;
b++) {
316 float s =
ab / 255.0f;
318 int trunc = (
int)floorf(
s);
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;
347 static const int32_t gTriples[] = {
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];
369 for (
int j = 0; j < 1000; j++) {
370 int ix = rand.
nextS();
393 if (
v2.setLength(1.0f)) {
401 uint32_t testVal = 0;
405 for (
int i = 0; i < 32; ++i) {
406 uint32_t testVal = 0x1 << i;
409 testVal ^= 0xFFFFFFFF;
414 uint32_t testVal = 0xFFFFFFFF;
419 for (
int i = 0; i < 100; ++i) {
420 int expectedNumSetBits = 0;
421 uint32_t testVal = 0;
424 for (
int j = 0; j < numTries; ++j) {
427 if (testVal & (0x1 << bit)) {
431 ++expectedNumSetBits;
432 testVal |= 0x1 << bit;
441 uint32_t testVal = 0x1;
442 uint32_t recreated = 0;
444 recreated |= (0x1 <<
result);
449 uint32_t testVal = 0x80000000;
450 uint32_t recreated = 0;
452 recreated |= (0x1 <<
result);
457 uint32_t testVal = 0x55555555;
458 uint32_t recreated = 0;
459 for (
int i = 0; i < 16; ++i) {
462 recreated |= (0x1 <<
result);
468 for (
int i = 0; i < 100; ++i) {
469 int expectedNumSetBits = 0;
470 uint32_t testVal = 0;
473 for (
int j = 0; j < numTries; ++j) {
476 if (testVal & (0x1 << bit)) {
480 ++expectedNumSetBits;
481 testVal |= 0x1 << bit;
485 uint32_t recreated = 0;
487 for (
int j = 0; j < expectedNumSetBits; ++j) {
489 recreated |= (0x1 << index);
512 if (
sizeof(
size_t) > 4) {
529 for (i = 0; i < 10000; i++) {
561 unittest_isfinite<double>(
reporter);
566 for (i = 0; i < 10000; i++) {
582 ERRORF(
reporter,
"\nFixed Divide: %8x / %8x -> %8x %8" PRIx64
"\n",
583 (uint32_t)numer, (uint32_t)denom, (uint32_t)
result, (uint64_t)
check);
610 { 0xFFFFFFFF, 0xFFFFFFFF },
611 { 0x11223344, 0x44332211 },
615 { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL },
616 { 0x1122334455667788ULL, 0x8877665544332211ULL },
623 for (
size_t i = 0; i < std::size(g16); ++i) {
626 for (
size_t i = 0; i < std::size(g32); ++i) {
629 for (
size_t i = 0; i < std::size(g64); ++i) {
636#if !defined(__MSVC_RUNTIME_CHECKS)
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;
661 for (
size_t i = 0; i < 10000; i++) {
662 const T numer = (
T)rand.
nextS();
676 test_divmod<uint8_t>(r);
680 test_divmod<uint16_t>(r);
684 test_divmod<uint32_t>(r);
688 test_divmod<uint64_t>(r);
692 test_divmod<int8_t>(r);
696 test_divmod<int16_t>(r);
700 test_divmod<int32_t>(r);
704 test_divmod<int64_t>(r);
715 constexpr int kNumSizeTBits = 8 *
sizeof(size_t);
717 size_t test = 0, expectedAns = 1;
721 test = 1; expectedAns = 1;
723 for (
int i = 1; i < kNumSizeTBits; ++i) {
736 test <<= kNumSizeTBits-1;
761 for (
auto r : recs) {
766 SkScalar p = SkTPin<SkScalar>(r.fFloat, 0, 100);
787 for (
auto r : recs) {
811 for (
auto r : recs) {
817#if defined(__ARM_NEON)
818 #include <arm_neon.h>
822 for (
int v = 0; v <= 255*255; v++) {
823 int want = (v + 127)/255;
825 uint16x8_t
V = vdupq_n_u16(v);
826 int got = vrshrq_n_u16(vrsraq_n_u16(
V,
V, 8), 8)[0];
829 SkDebugf(
"%d -> %d, want %d\n", v, got, want);
static void fail(const SkString &err)
static void round(SkPoint *p)
static float float_blend(int src, int dst, float unit)
static int blend31_old(int src, int dst, int a31)
static void test_copysign(skiatest::Reporter *reporter)
static void test_muldiv255ceiling(skiatest::Reporter *reporter)
static void test_divmod(skiatest::Reporter *r)
static int blend31_slow(int src, int dst, int a31)
static void unittest_isfinite(skiatest::Reporter *reporter)
static void huge_vector_normalize(skiatest::Reporter *reporter)
static float fast_floor(float x)
static void check_length(skiatest::Reporter *reporter, const SkPoint &p, SkScalar targetLen)
static void test_blend31()
static int blend31(int src, int dst, int a31)
static void test_floor(skiatest::Reporter *reporter)
static void test_clz(skiatest::Reporter *reporter)
static int blend31_round(int src, int dst, int a31)
static float sk_fsel(float pred, float result_ge, float result_lt)
static void test_ctz(skiatest::Reporter *reporter)
static void test_muldiv255(skiatest::Reporter *reporter)
static void test_nextsizepow2(skiatest::Reporter *r, size_t test, size_t expectedAns)
static void test_floor_value(skiatest::Reporter *reporter, float value)
static void test_rsqrt(skiatest::Reporter *reporter, RSqrtFn rsqrt)
static float std_floor(float x)
static int(* blend_functions[])(int, int, int)
static void unittest_half(skiatest::Reporter *reporter)
#define check(reporter, ref, unref, make, kill)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static uint64_t SkEndianSwap64(uint64_t value)
static uint16_t SkEndianSwap16(uint16_t value)
static constexpr uint32_t SkEndianSwap32(uint32_t value)
static SkFixed SkFixedCeilToFixed(SkFixed x)
#define SkFixedDiv(numer, denom)
static SkFixed SkFixedFloorToFixed(SkFixed x)
static SkFixed SkFixedRoundToFixed(SkFixed x)
constexpr int64_t SK_MinS64FitsInFloat
static bool SkIsFinite(T x, Pack... values)
static constexpr int64_t sk_float_saturate2int64(float x)
constexpr int64_t SK_MaxS64FitsInFloat
constexpr int SK_MinS32FitsInFloat
static float sk_float_rsqrt_portable(float x)
constexpr int SK_MaxS32FitsInFloat
static float sk_float_rsqrt(float x)
static constexpr int sk_double_saturate2int(double x)
static constexpr int sk_float_saturate2int(float x)
float SkHalfToFloat(SkHalf h)
SkHalf SkFloatToHalf(float f)
int SkNthSet(uint32_t target, int n)
static int SkPopCount(uint32_t n)
constexpr int SkCTZ_portable(uint32_t x)
Returns the number of trailing zero bits (0...32)
static int SkCTZ(uint32_t mask)
static U8CPU SkMulDiv255Trunc(U8CPU a, U8CPU b)
static U8CPU SkMulDiv255Ceiling(U8CPU a, U8CPU b)
void SkTDivMod(In numer, In denom, Out *div, Out *mod)
static int32_t SkCopySign32(int32_t x, int32_t y)
constexpr int SkCLZ_portable(uint32_t x)
Returns the number of leading zero bits (0...32)
static int SkCLZ(uint32_t mask)
static size_t GrNextSizePow2(size_t n)
static constexpr int64_t SK_MaxS64
static U8CPU SkMulDiv255Round(U16CPU a, U16CPU b)
static constexpr int32_t SkLeftShift(int32_t value, int32_t shift)
static constexpr int32_t SK_NaN32
static constexpr int32_t SK_MinS32
static constexpr int64_t SK_MinS64
static constexpr int32_t SK_MaxS32
#define SkScalarCopySign(x, y)
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
#define SkScalarRoundToInt(x)
#define SK_ScalarInfinity
#define SK_ScalarNegativeInfinity
constexpr int8_t SkToS8(S x)
constexpr uint16_t SkToU16(S x)
constexpr int32_t SkToS32(S x)
constexpr uint8_t SkToU8(S x)
constexpr int16_t SkToS16(S x)
constexpr uint32_t SkToU32(S x)
#define DEF_TEST(name, reporter)
#define REPORTER_ASSERT(r, cond,...)
Type::kYUV Type::kRGBA() int(0.7 *637)
uint32_t nextULessThan(uint32_t count)
uint32_t nextRangeU(uint32_t min, uint32_t max)
T __attribute__((ext_vector_type(N))) V