1/* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "SkNx.h" 9#include "SkRandom.h" 10#include "Test.h" 11 12template <int N, typename T> 13static void test_Nf(skiatest::Reporter* r) { 14 15 auto assert_nearly_eq = [&](double eps, const SkNf<N,T>& v, T a, T b, T c, T d) { 16 auto close = [=](T a, T b) { return fabs(a-b) <= eps; }; 17 T vals[4]; 18 v.store(vals); 19 bool ok = close(vals[0], a) && close(vals[1], b) 20 && close(v.template kth<0>(), a) && close(v.template kth<1>(), b); 21 REPORTER_ASSERT(r, ok); 22 if (N == 4) { 23 ok = close(vals[2], c) && close(vals[3], d) 24 && close(v.template kth<2>(), c) && close(v.template kth<3>(), d); 25 REPORTER_ASSERT(r, ok); 26 } 27 }; 28 auto assert_eq = [&](const SkNf<N,T>& v, T a, T b, T c, T d) { 29 return assert_nearly_eq(0, v, a,b,c,d); 30 }; 31 32 T vals[] = {3, 4, 5, 6}; 33 SkNf<N,T> a = SkNf<N,T>::Load(vals), 34 b(a), 35 c = a; 36 SkNf<N,T> d; 37 d = a; 38 39 assert_eq(a, 3, 4, 5, 6); 40 assert_eq(b, 3, 4, 5, 6); 41 assert_eq(c, 3, 4, 5, 6); 42 assert_eq(d, 3, 4, 5, 6); 43 44 assert_eq(a+b, 6, 8, 10, 12); 45 assert_eq(a*b, 9, 16, 25, 36); 46 assert_eq(a*b-b, 6, 12, 20, 30); 47 assert_eq((a*b).sqrt(), 3, 4, 5, 6); 48 assert_eq(a/b, 1, 1, 1, 1); 49 assert_eq(-a, -3, -4, -5, -6); 50 51 SkNf<N,T> fours(4); 52 53 assert_eq(fours.sqrt(), 2,2,2,2); 54 assert_nearly_eq(0.001, fours.rsqrt0(), 0.5, 0.5, 0.5, 0.5); 55 assert_nearly_eq(0.001, fours.rsqrt1(), 0.5, 0.5, 0.5, 0.5); 56 assert_nearly_eq(0.001, fours.rsqrt2(), 0.5, 0.5, 0.5, 0.5); 57 58 assert_eq( fours. invert(), 0.25, 0.25, 0.25, 0.25); 59 assert_nearly_eq(0.001, fours.approxInvert(), 0.25, 0.25, 0.25, 0.25); 60 61 assert_eq(SkNf<N,T>::Min(a, fours), 3, 4, 4, 4); 62 assert_eq(SkNf<N,T>::Max(a, fours), 4, 4, 5, 6); 63 64 // Test some comparisons. This is not exhaustive. 65 REPORTER_ASSERT(r, (a == b).allTrue()); 66 REPORTER_ASSERT(r, (a+b == a*b-b).anyTrue()); 67 REPORTER_ASSERT(r, !(a+b == a*b-b).allTrue()); 68 REPORTER_ASSERT(r, !(a+b == a*b).anyTrue()); 69 REPORTER_ASSERT(r, !(a != b).anyTrue()); 70 REPORTER_ASSERT(r, (a < fours).anyTrue()); 71 REPORTER_ASSERT(r, (a <= fours).anyTrue()); 72 REPORTER_ASSERT(r, !(a > fours).allTrue()); 73 REPORTER_ASSERT(r, !(a >= fours).allTrue()); 74} 75 76DEF_TEST(SkNf, r) { 77 test_Nf<2, float>(r); 78 test_Nf<2, double>(r); 79 80 test_Nf<4, float>(r); 81 test_Nf<4, double>(r); 82} 83 84template <int N, typename T> 85void test_Ni(skiatest::Reporter* r) { 86 auto assert_eq = [&](const SkNi<N,T>& v, T a, T b, T c, T d, T e, T f, T g, T h) { 87 T vals[8]; 88 v.store(vals); 89 90 switch (N) { 91 case 8: REPORTER_ASSERT(r, vals[4] == e && vals[5] == f && vals[6] == g && vals[7] == h); 92 case 4: REPORTER_ASSERT(r, vals[2] == c && vals[3] == d); 93 case 2: REPORTER_ASSERT(r, vals[0] == a && vals[1] == b); 94 } 95 switch (N) { 96 case 8: REPORTER_ASSERT(r, v.template kth<4>() == e && v.template kth<5>() == f && 97 v.template kth<6>() == g && v.template kth<7>() == h); 98 case 4: REPORTER_ASSERT(r, v.template kth<2>() == c && v.template kth<3>() == d); 99 case 2: REPORTER_ASSERT(r, v.template kth<0>() == a && v.template kth<1>() == b); 100 } 101 }; 102 103 T vals[] = { 1,2,3,4,5,6,7,8 }; 104 SkNi<N,T> a = SkNi<N,T>::Load(vals), 105 b(a), 106 c = a; 107 SkNi<N,T> d; 108 d = a; 109 110 assert_eq(a, 1,2,3,4,5,6,7,8); 111 assert_eq(b, 1,2,3,4,5,6,7,8); 112 assert_eq(c, 1,2,3,4,5,6,7,8); 113 assert_eq(d, 1,2,3,4,5,6,7,8); 114 115 assert_eq(a+a, 2,4,6,8,10,12,14,16); 116 assert_eq(a*a, 1,4,9,16,25,36,49,64); 117 assert_eq(a*a-a, 0,2,6,12,20,30,42,56); 118 119 assert_eq(a >> 2, 0,0,0,1,1,1,1,2); 120 assert_eq(a << 1, 2,4,6,8,10,12,14,16); 121 122 REPORTER_ASSERT(r, a.template kth<1>() == 2); 123} 124 125DEF_TEST(SkNi, r) { 126 test_Ni<2, uint16_t>(r); 127 test_Ni<4, uint16_t>(r); 128 test_Ni<8, uint16_t>(r); 129 130 test_Ni<2, int>(r); 131 test_Ni<4, int>(r); 132 test_Ni<8, int>(r); 133} 134 135DEF_TEST(SkNi_min, r) { 136 // Exhaustively check the 8x8 bit space. 137 for (int a = 0; a < (1<<8); a++) { 138 for (int b = 0; b < (1<<8); b++) { 139 REPORTER_ASSERT(r, Sk16b::Min(Sk16b(a), Sk16b(b)).kth<0>() == SkTMin(a, b)); 140 }} 141 142 // Exhausting the 16x16 bit space is kind of slow, so only do that in release builds. 143#ifdef SK_DEBUG 144 SkRandom rand; 145 for (int i = 0; i < (1<<16); i++) { 146 uint16_t a = rand.nextU() >> 16, 147 b = rand.nextU() >> 16; 148 REPORTER_ASSERT(r, Sk8h::Min(Sk8h(a), Sk8h(b)).kth<0>() == SkTMin(a, b)); 149 } 150#else 151 for (int a = 0; a < (1<<16); a++) { 152 for (int b = 0; b < (1<<16); b++) { 153 REPORTER_ASSERT(r, Sk8h::Min(Sk8h(a), Sk8h(b)).kth<0>() == SkTMin(a, b)); 154 }} 155#endif 156} 157