| 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 |