aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
authorGravatar mtklein <mtklein@chromium.org>2015-03-30 10:50:27 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-03-30 10:50:27 -0700
commitc9adb05b64fa0bfadf9d1a782afcda470da68c9e (patch)
tree6413cc149b70ae36181e9f0789246b9db24447f0 /tests
parent23ac62c83a49d675a38f1c20462b5537f3c8af01 (diff)
Refactor Sk2x<T> + Sk4x<T> into SkNf<N,T> and SkNi<N,T>
The primary feature this delivers is SkNf and SkNd for arbitrary power-of-two N. Non-specialized types or types larger than 128 bits should now Just Work (and we can drop in a specialization to make them faster). Sk4s is now just a typedef for SkNf<4, SkScalar>; Sk4d is SkNf<4, double>, Sk2f SkNf<2, float>, etc. This also makes implementing new specializations easier and more encapsulated. We're now using template specialization, which means the specialized versions don't have to leak out so much from SkNx_sse.h and SkNx_neon.h. This design leaves us room to grow up, e.g to SkNf<8, SkScalar> == Sk8s, and to grown down too, to things like SkNi<8, uint16_t> == Sk8h. To simplify things, I've stripped away most APIs (swizzles, casts, reinterpret_casts) that no one's using yet. I will happily add them back if they seem useful. You shouldn't feel bad about using any of the typedef Sk4s, Sk4f, Sk4d, Sk2s, Sk2f, Sk2d, Sk4i, etc. Here's how you should feel: - Sk4f, Sk4s, Sk2d: feel awesome - Sk2f, Sk2s, Sk4d: feel pretty good No public API changes. TBR=reed@google.com BUG=skia:3592 Review URL: https://codereview.chromium.org/1048593002
Diffstat (limited to 'tests')
-rw-r--r--tests/PMFloatTest.cpp6
-rw-r--r--tests/Sk2xTest.cpp68
-rw-r--r--tests/Sk4xTest.cpp145
-rw-r--r--tests/SkNxTest.cpp78
4 files changed, 81 insertions, 216 deletions
diff --git a/tests/PMFloatTest.cpp b/tests/PMFloatTest.cpp
index 309cd60f4a..435969c21f 100644
--- a/tests/PMFloatTest.cpp
+++ b/tests/PMFloatTest.cpp
@@ -32,9 +32,9 @@ DEF_TEST(SkPMFloat, r) {
REPORTER_ASSERT(r, SkScalarNearlyEqual( 1.0f, clamped.g()));
REPORTER_ASSERT(r, SkScalarNearlyEqual( 0.0f, clamped.b()));
- // Test SkPMFloat <-> Sk4f conversion.
- Sk4f fs = clamped;
- SkPMFloat scaled = fs * Sk4f(0.25f);
+ // Test SkPMFloat <-> Sk4s conversion.
+ Sk4s fs = clamped;
+ SkPMFloat scaled = fs * Sk4s(0.25f);
REPORTER_ASSERT(r, SkScalarNearlyEqual(63.75f, scaled.a()));
REPORTER_ASSERT(r, SkScalarNearlyEqual(38.25f, scaled.r()));
REPORTER_ASSERT(r, SkScalarNearlyEqual( 0.25f, scaled.g()));
diff --git a/tests/Sk2xTest.cpp b/tests/Sk2xTest.cpp
deleted file mode 100644
index 40e90913a5..0000000000
--- a/tests/Sk2xTest.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "Test.h"
-#include "Sk2x.h"
-
-template <typename T>
-static bool nearly_eq(double eps, const Sk2x<T>& v, double x, double y) {
- T vals[2];
- v.store(vals);
- return fabs(vals[0] - (T)x) <= eps && fabs(vals[1] - (T)y) <= eps;
-}
-
-template <typename T>
-static bool eq(const Sk2x<T>& v, double x, double y) { return nearly_eq(0, v, x, y); }
-
-template <typename T>
-static void test(skiatest::Reporter* r) {
- // Constructors, assignment, etc.
- Sk2x<T> a(4),
- b = a,
- c(a);
- REPORTER_ASSERT(r, eq(a, 4, 4));
- REPORTER_ASSERT(r, eq(b, 4, 4));
- REPORTER_ASSERT(r, eq(c, 4, 4));
-
- Sk2x<T> d(2, 5);
- Sk2x<T> e;
- e = d;
- T vals[] = { 2, 5 };
- Sk2x<T> f = Sk2x<T>::Load(vals);
- REPORTER_ASSERT(r, eq(d, 2, 5));
- REPORTER_ASSERT(r, eq(e, 2, 5));
- REPORTER_ASSERT(r, eq(f, 2, 5));
-
- a.store(vals);
- REPORTER_ASSERT(r, vals[0] == 4 && vals[1] == 4);
-
- // Math
- REPORTER_ASSERT(r, eq(a + d, 6, 9));
- REPORTER_ASSERT(r, eq(a - d, 2, -1));
- REPORTER_ASSERT(r, eq(a * d, 8, 20));
- REPORTER_ASSERT(r, eq(a / d, 2, 0.8));
-
- REPORTER_ASSERT(r, nearly_eq(0.001, a.rsqrt(), 0.5, 0.5));
- REPORTER_ASSERT(r, eq(a.sqrt(), 2, 2));
-
- REPORTER_ASSERT(r, nearly_eq(0.001, d.approxInvert(), 0.5, 0.2));
- REPORTER_ASSERT(r, eq(d.invert(), 0.5, 0.2));
-
- REPORTER_ASSERT(r, eq(Sk2x<T>::Min(a, d), 2, 4));
- REPORTER_ASSERT(r, eq(Sk2x<T>::Max(a, d), 4, 5));
-
- REPORTER_ASSERT(r, eq(-d, -2, -5));
-
- // A bit of both.
- a += d;
- a *= d;
- a -= d;
- REPORTER_ASSERT(r, eq(a, 10, 40));
-}
-
-DEF_TEST(Sk2f, r) { test< float>(r); }
-DEF_TEST(Sk2d, r) { test<double>(r); }
diff --git a/tests/Sk4xTest.cpp b/tests/Sk4xTest.cpp
deleted file mode 100644
index 4dc4c3621c..0000000000
--- a/tests/Sk4xTest.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-#include "Test.h"
-#include "Sk4x.h"
-
-#define ASSERT_EQ(a, b) REPORTER_ASSERT(r, a.equal(b).allTrue())
-#define ASSERT_NE(a, b) REPORTER_ASSERT(r, a.notEqual(b).allTrue())
-
-DEF_TEST(Sk4x_Construction, r) {
- Sk4f uninitialized;
- Sk4f zero(0,0,0,0);
- Sk4f foo(1,2,3,4),
- bar(foo),
- baz = bar;
- ASSERT_EQ(foo, bar);
- ASSERT_EQ(bar, baz);
- ASSERT_EQ(baz, foo);
-}
-
-struct AlignedFloats {
- Sk4f forces16ByteAlignment; // On 64-bit machines, the stack starts 128-bit aligned,
- float fs[5]; // but not necessarily so on 32-bit. Adding an Sk4f forces it.
-};
-
-DEF_TEST(Sk4x_LoadStore, r) {
- AlignedFloats aligned;
- // fs will be 16-byte aligned, fs+1 not.
- float* fs = aligned.fs;
- for (int i = 0; i < 5; i++) { // set to 5,6,7,8,9
- fs[i] = float(i+5);
- }
-
- Sk4f foo = Sk4f::Load(fs);
- Sk4f bar = Sk4f::LoadAligned(fs);
- ASSERT_EQ(foo, bar);
-
- foo = Sk4f::Load(fs+1);
- ASSERT_NE(foo, bar);
-
- foo.storeAligned(fs);
- bar.store(fs+1);
- REPORTER_ASSERT(r, fs[0] == 6 &&
- fs[1] == 5 &&
- fs[2] == 6 &&
- fs[3] == 7 &&
- fs[4] == 8);
-}
-
-DEF_TEST(Sk4x_Conversions, r) {
- // Assuming IEEE floats.
- Sk4f zerof(0,0,0,0);
- Sk4i zeroi(0,0,0,0);
- ASSERT_EQ(zeroi, zerof.cast<Sk4i>());
- ASSERT_EQ(zeroi, zerof.reinterpret<Sk4i>());
- ASSERT_EQ(zerof, zeroi.cast<Sk4f>());
- ASSERT_EQ(zerof, zeroi.reinterpret<Sk4f>());
-
- Sk4f twof(2,2,2,2);
- Sk4i twoi(2,2,2,2);
- ASSERT_EQ(twoi, twof.cast<Sk4i>());
- ASSERT_NE(twoi, twof.reinterpret<Sk4i>());
- ASSERT_EQ(twof, twoi.cast<Sk4f>());
- ASSERT_NE(twof, twoi.reinterpret<Sk4f>());
-
- ASSERT_EQ(Sk4i(0,0,0,0), Sk4f(0.5f, 0.49f, 0.51f, 0.99f).cast<Sk4i>());
- ASSERT_EQ(Sk4i(1,1,1,1), Sk4f(1.5f, 1.49f, 1.51f, 1.99f).cast<Sk4i>());
-}
-
-DEF_TEST(Sk4x_Bits, r) {
- ASSERT_EQ(Sk4i(0,0,0,0).bitNot(), Sk4i(-1,-1,-1,-1));
-
- Sk4i a(2,3,4,5),
- b(1,3,5,7);
- ASSERT_EQ(Sk4i(0,3,4,5), a & b);
- ASSERT_EQ(Sk4i(3,3,5,7), a | b);
-}
-
-DEF_TEST(Sk4x_Arith, r) {
- ASSERT_EQ(Sk4f(4,6,8,10), Sk4f(1,2,3,4) + Sk4f(3,4,5,6));
- ASSERT_EQ(Sk4f(-2,-2,-2,-2), Sk4f(1,2,3,4) - Sk4f(3,4,5,6));
- ASSERT_EQ(Sk4f(3,8,15,24), Sk4f(1,2,3,4) * Sk4f(3,4,5,6));
-
- ASSERT_EQ(Sk4f(-1,-2,-3,-4), -Sk4f(1,2,3,4));
-
- float third = 1.0f/3.0f;
- ASSERT_EQ(Sk4f(1*third, 0.5f, 0.6f, 2*third), Sk4f(1,2,3,4) / Sk4f(3,4,5,6));
- ASSERT_EQ(Sk4i(4,6,8,10), Sk4i(1,2,3,4) + Sk4i(3,4,5,6));
- ASSERT_EQ(Sk4i(-2,-2,-2,-2), Sk4i(1,2,3,4) - Sk4i(3,4,5,6));
- ASSERT_EQ(Sk4i(3,8,15,24), Sk4i(1,2,3,4) * Sk4i(3,4,5,6));
-}
-
-DEF_TEST(Sk4x_ExplicitPromotion, r) {
- ASSERT_EQ(Sk4f(2,4,6,8), Sk4f(1,2,3,4) * Sk4f(2.0f));
-}
-
-DEF_TEST(Sk4x_Sqrt, r) {
- Sk4f squares(4, 16, 25, 121),
- roots(2, 4, 5, 11);
- // .sqrt() should be pretty precise.
- Sk4f error = roots.subtract(squares.sqrt());
- REPORTER_ASSERT(r, (error > Sk4f(-0.000001f)).allTrue());
- REPORTER_ASSERT(r, (error < Sk4f(+0.000001f)).allTrue());
-
- // .rsqrt() isn't so precise (for SSE), but should be pretty close.
- error = roots.subtract(squares.multiply(squares.rsqrt()));
- REPORTER_ASSERT(r, (error > Sk4f(-0.01f)).allTrue());
- REPORTER_ASSERT(r, (error < Sk4f(+0.01f)).allTrue());
-}
-
-DEF_TEST(Sk4x_Comparison, r) {
- ASSERT_EQ(Sk4f(1,2,3,4), Sk4f(1,2,3,4));
- ASSERT_NE(Sk4f(4,3,2,1), Sk4f(1,2,3,4));
-
- ASSERT_EQ(Sk4i(-1,-1,0,-1), Sk4f(1,2,5,4) == Sk4f(1,2,3,4));
-
- ASSERT_EQ(Sk4i(-1,-1,-1,-1), Sk4f(1,2,3,4) < Sk4f(2,3,4,5));
- ASSERT_EQ(Sk4i(-1,-1,-1,-1), Sk4f(1,2,3,4) <= Sk4f(2,3,4,5));
- ASSERT_EQ(Sk4i(0,0,0,0), Sk4f(1,2,3,4) > Sk4f(2,3,4,5));
- ASSERT_EQ(Sk4i(0,0,0,0), Sk4f(1,2,3,4) >= Sk4f(2,3,4,5));
-
- ASSERT_EQ(Sk4i(1,2,3,4), Sk4i(1,2,3,4));
- ASSERT_NE(Sk4i(4,3,2,1), Sk4i(1,2,3,4));
-
- ASSERT_EQ(Sk4i(-1,-1,0,-1), Sk4i(1,2,5,4) == Sk4i(1,2,3,4));
-
- ASSERT_EQ(Sk4i(-1,-1,-1,-1), Sk4i(1,2,3,4) < Sk4i(2,3,4,5));
- ASSERT_EQ(Sk4i(-1,-1,-1,-1), Sk4i(1,2,3,4) <= Sk4i(2,3,4,5));
- ASSERT_EQ(Sk4i(0,0,0,0), Sk4i(1,2,3,4) > Sk4i(2,3,4,5));
- ASSERT_EQ(Sk4i(0,0,0,0), Sk4i(1,2,3,4) >= Sk4i(2,3,4,5));
-}
-
-DEF_TEST(Sk4x_MinMax, r) {
- ASSERT_EQ(Sk4f(1,2,2,1), Sk4f::Min(Sk4f(1,2,3,4), Sk4f(4,3,2,1)));
- ASSERT_EQ(Sk4f(4,3,3,4), Sk4f::Max(Sk4f(1,2,3,4), Sk4f(4,3,2,1)));
- ASSERT_EQ(Sk4i(1,2,2,1), Sk4i::Min(Sk4i(1,2,3,4), Sk4i(4,3,2,1)));
- ASSERT_EQ(Sk4i(4,3,3,4), Sk4i::Max(Sk4i(1,2,3,4), Sk4i(4,3,2,1)));
-}
-
-DEF_TEST(Sk4x_Swizzle, r) {
- ASSERT_EQ(Sk4f(1,2,3,4).badc(), Sk4f(2,1,4,3));
- ASSERT_EQ(Sk4f(1,2,3,4).aacc(), Sk4f(1,1,3,3));
- ASSERT_EQ(Sk4f(1,2,3,4).bbdd(), Sk4f(2,2,4,4));
-
- ASSERT_EQ(Sk4i(1,2,3,4).badc(), Sk4i(2,1,4,3));
- ASSERT_EQ(Sk4i(1,2,3,4).aacc(), Sk4i(1,1,3,3));
- ASSERT_EQ(Sk4i(1,2,3,4).bbdd(), Sk4i(2,2,4,4));
-}
diff --git a/tests/SkNxTest.cpp b/tests/SkNxTest.cpp
new file mode 100644
index 0000000000..1edf5b44b9
--- /dev/null
+++ b/tests/SkNxTest.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkNx.h"
+#include "Test.h"
+
+template <int N, typename T>
+static void test_Nf(skiatest::Reporter* r) {
+
+ auto assert_nearly_eq = [&](double eps, const SkNf<N,T>& v, T a, T b, T c, T d) {
+ auto close = [=](T a, T b) { return fabs(a-b) <= eps; };
+ T vals[4];
+ v.store(vals);
+ REPORTER_ASSERT(r, close(vals[0], a) && close(vals[1], b));
+ REPORTER_ASSERT(r, close( v[0], a) && close( v[1], b));
+
+ if (N == 4) {
+ REPORTER_ASSERT(r, close(vals[2], c) && close(vals[3], d));
+ REPORTER_ASSERT(r, close( v[2], c) && close( v[3], d));
+ }
+ };
+ auto assert_eq = [&](const SkNf<N,T>& v, T a, T b, T c, T d) {
+ return assert_nearly_eq(0, v, a,b,c,d);
+ };
+
+ T vals[] = {3, 4, 5, 6};
+ SkNf<N,T> a = SkNf<N,T>::Load(vals),
+ b(a),
+ c = a;
+ SkNf<N,T> d;
+ d = a;
+
+ assert_eq(a, 3, 4, 5, 6);
+ assert_eq(b, 3, 4, 5, 6);
+ assert_eq(c, 3, 4, 5, 6);
+ assert_eq(d, 3, 4, 5, 6);
+
+ assert_eq(a+b, 6, 8, 10, 12);
+ assert_eq(a*b, 9, 16, 25, 36);
+ assert_eq(a*b-b, 6, 12, 20, 30);
+ assert_eq((a*b).sqrt(), 3, 4, 5, 6);
+ assert_eq(a/b, 1, 1, 1, 1);
+ assert_eq(-a, -3, -4, -5, -6);
+
+ SkNf<N,T> fours(4);
+
+ assert_eq(fours.sqrt(), 2,2,2,2);
+ assert_nearly_eq(0.001, fours.rsqrt(), 0.5, 0.5, 0.5, 0.5);
+
+ assert_eq( fours. invert(), 0.25, 0.25, 0.25, 0.25);
+ assert_nearly_eq(0.001, fours.approxInvert(), 0.25, 0.25, 0.25, 0.25);
+
+ assert_eq(SkNf<N,T>::Min(a, fours), 3, 4, 4, 4);
+ assert_eq(SkNf<N,T>::Max(a, fours), 4, 4, 5, 6);
+
+ // Test some comparisons. This is not exhaustive.
+ REPORTER_ASSERT(r, (a == b).allTrue());
+ REPORTER_ASSERT(r, (a+b == a*b-b).anyTrue());
+ REPORTER_ASSERT(r, !(a+b == a*b-b).allTrue());
+ REPORTER_ASSERT(r, !(a+b == a*b).anyTrue());
+ REPORTER_ASSERT(r, !(a != b).anyTrue());
+ REPORTER_ASSERT(r, (a < fours).anyTrue());
+ REPORTER_ASSERT(r, (a <= fours).anyTrue());
+ REPORTER_ASSERT(r, !(a > fours).allTrue());
+ REPORTER_ASSERT(r, !(a >= fours).allTrue());
+}
+
+DEF_TEST(SkNf, r) {
+ test_Nf<2, float>(r);
+ test_Nf<2, double>(r);
+
+ test_Nf<4, float>(r);
+ test_Nf<4, double>(r);
+}