OLD | NEW |
| (Empty) |
1 // It is important _not_ to put header guards here. | |
2 // This file will be intentionally included three times. | |
3 | |
4 #include "SkTypes.h" // Keep this before any #ifdef for skbug.com/3362 | |
5 | |
6 #if defined(SK4X_PREAMBLE) | |
7 #include "SkFloatingPoint.h" | |
8 #include <math.h> | |
9 | |
10 #elif defined(SK4X_PRIVATE) | |
11 typedef T Type; | |
12 typedef T Vector[4]; | |
13 | |
14 Vector fVec; | |
15 | |
16 template <int m, int a, int s, int k> | |
17 static Sk4x Shuffle(const Sk4x&, const Sk4x&); | |
18 | |
19 void set(const T vals[4]) { for (int i = 0; i < 4; i++) { fVec[i] = vals[i];
} } | |
20 | |
21 #else | |
22 | |
23 #define M(...) template <typename T> __VA_ARGS__ Sk4x<T>:: | |
24 | |
25 M() Sk4x() {} | |
26 M() Sk4x(T v) { fVec[0] = fVec[1] = fVec[2] = fVec[3] = v; } | |
27 M() Sk4x(T a, T b, T c, T d) { fVec[0] = a; fVec[1] = b; fVec[2] = c; fVec[3] =
d; } | |
28 | |
29 M() Sk4x(const Sk4x<T>& other) { this->set(other.fVec);
} | |
30 M(Sk4x<T>&) operator=(const Sk4x<T>& other) { this->set(other.fVec); return *thi
s; } | |
31 | |
32 M(Sk4x<T>) Load (const T vals[4]) { Sk4x r; r.set(vals); return r; } | |
33 M(Sk4x<T>) LoadAligned(const T vals[4]) { return Load(vals); } | |
34 | |
35 M(void) store (T vals[4]) const { for (int i = 0; i < 4; i++) { vals[i] =
fVec[i]; } } | |
36 M(void) storeAligned(T vals[4]) const { this->store(vals); } | |
37 | |
38 M(template <typename Dst> Dst) reinterpret() const { | |
39 Dst d; | |
40 memcpy(&d.fVec, fVec, sizeof(fVec)); | |
41 return d; | |
42 } | |
43 M(template <typename Dst> Dst) cast() const { | |
44 return Dst((typename Dst::Type)fVec[0], | |
45 (typename Dst::Type)fVec[1], | |
46 (typename Dst::Type)fVec[2], | |
47 (typename Dst::Type)fVec[3]); | |
48 } | |
49 | |
50 M(bool) allTrue() const { return fVec[0] && fVec[1] && fVec[2] && fVec[3]; } | |
51 M(bool) anyTrue() const { return fVec[0] || fVec[1] || fVec[2] || fVec[3]; } | |
52 | |
53 M(Sk4x<T>) bitNot() const { return Sk4x(~fVec[0], ~fVec[1], ~fVec[2], ~fVec[3]);
} | |
54 | |
55 #define BINOP(op) fVec[0] op other.fVec[0], \ | |
56 fVec[1] op other.fVec[1], \ | |
57 fVec[2] op other.fVec[2], \ | |
58 fVec[3] op other.fVec[3] | |
59 M(Sk4x<T>) bitAnd(const Sk4x& other) const { return Sk4x(BINOP(&)); } | |
60 M(Sk4x<T>) bitOr(const Sk4x& other) const { return Sk4x(BINOP(|)); } | |
61 M(Sk4x<T>) add(const Sk4x<T>& other) const { return Sk4x(BINOP(+)); } | |
62 M(Sk4x<T>) subtract(const Sk4x<T>& other) const { return Sk4x(BINOP(-)); } | |
63 M(Sk4x<T>) multiply(const Sk4x<T>& other) const { return Sk4x(BINOP(*)); } | |
64 M(Sk4x<T>) divide(const Sk4x<T>& other) const { return Sk4x(BINOP(/)); } | |
65 #undef BINOP | |
66 | |
67 template<> inline Sk4f Sk4f::rsqrt() const { | |
68 return Sk4f(sk_float_rsqrt(fVec[0]), | |
69 sk_float_rsqrt(fVec[1]), | |
70 sk_float_rsqrt(fVec[2]), | |
71 sk_float_rsqrt(fVec[3])); | |
72 } | |
73 | |
74 template<> inline Sk4f Sk4f::sqrt() const { | |
75 return Sk4f(sqrtf(fVec[0]), | |
76 sqrtf(fVec[1]), | |
77 sqrtf(fVec[2]), | |
78 sqrtf(fVec[3])); | |
79 } | |
80 | |
81 #define BOOL_BINOP(op) fVec[0] op other.fVec[0] ? -1 : 0, \ | |
82 fVec[1] op other.fVec[1] ? -1 : 0, \ | |
83 fVec[2] op other.fVec[2] ? -1 : 0, \ | |
84 fVec[3] op other.fVec[3] ? -1 : 0 | |
85 M(Sk4i) equal(const Sk4x<T>& other) const { return Sk4i(BOOL_BINOP(==
)); } | |
86 M(Sk4i) notEqual(const Sk4x<T>& other) const { return Sk4i(BOOL_BINOP(!=
)); } | |
87 M(Sk4i) lessThan(const Sk4x<T>& other) const { return Sk4i(BOOL_BINOP( <
)); } | |
88 M(Sk4i) greaterThan(const Sk4x<T>& other) const { return Sk4i(BOOL_BINOP( >
)); } | |
89 M(Sk4i) lessThanEqual(const Sk4x<T>& other) const { return Sk4i(BOOL_BINOP(<=
)); } | |
90 M(Sk4i) greaterThanEqual(const Sk4x<T>& other) const { return Sk4i(BOOL_BINOP(>=
)); } | |
91 #undef BOOL_BINOP | |
92 | |
93 M(Sk4x<T>) Min(const Sk4x<T>& a, const Sk4x<T>& b) { | |
94 return Sk4x(SkTMin(a.fVec[0], b.fVec[0]), | |
95 SkTMin(a.fVec[1], b.fVec[1]), | |
96 SkTMin(a.fVec[2], b.fVec[2]), | |
97 SkTMin(a.fVec[3], b.fVec[3])); | |
98 } | |
99 | |
100 M(Sk4x<T>) Max(const Sk4x<T>& a, const Sk4x<T>& b) { | |
101 return Sk4x(SkTMax(a.fVec[0], b.fVec[0]), | |
102 SkTMax(a.fVec[1], b.fVec[1]), | |
103 SkTMax(a.fVec[2], b.fVec[2]), | |
104 SkTMax(a.fVec[3], b.fVec[3])); | |
105 } | |
106 | |
107 M(template <int m, int a, int s, int k> Sk4x<T>) Shuffle(const Sk4x<T>& x, const
Sk4x<T>& y) { | |
108 return Sk4x(m < 4 ? x.fVec[m] : y.fVec[m-4], | |
109 a < 4 ? x.fVec[a] : y.fVec[a-4], | |
110 s < 4 ? x.fVec[s] : y.fVec[s-4], | |
111 k < 4 ? x.fVec[k] : y.fVec[k-4]); | |
112 } | |
113 | |
114 M(Sk4x<T>) aacc() const { return Shuffle<0,0,2,2>(*this, *this); } | |
115 M(Sk4x<T>) bbdd() const { return Shuffle<1,1,3,3>(*this, *this); } | |
116 M(Sk4x<T>) badc() const { return Shuffle<1,0,3,2>(*this, *this); } | |
117 | |
118 #undef M | |
119 | |
120 #endif | |
OLD | NEW |