OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef SkNx_DEFINED | 8 #ifndef SkNx_DEFINED |
9 #define SkNx_DEFINED | 9 #define SkNx_DEFINED |
10 | 10 |
(...skipping 14 matching lines...) Expand all Loading... |
25 | 25 |
26 // The default implementations just fall back on a pair of size N/2. | 26 // The default implementations just fall back on a pair of size N/2. |
27 // These support the union of operations we might do to ints and floats, but | 27 // These support the union of operations we might do to ints and floats, but |
28 // platform specializations might support fewer (e.g. no float <<, no int /). | 28 // platform specializations might support fewer (e.g. no float <<, no int /). |
29 template <int N, typename T> | 29 template <int N, typename T> |
30 class SkNx { | 30 class SkNx { |
31 public: | 31 public: |
32 SkNx() {} | 32 SkNx() {} |
33 SkNx(const SkNx<N/2, T>& lo, const SkNx<N/2, T>& hi) : fLo(lo), fHi(hi) {} | 33 SkNx(const SkNx<N/2, T>& lo, const SkNx<N/2, T>& hi) : fLo(lo), fHi(hi) {} |
34 SkNx(T val) : fLo(val), fHi(val) {} | 34 SkNx(T val) : fLo(val), fHi(val) {} |
35 static SkNx Load(const T vals[N]) { | 35 static SkNx Load(const void* ptr) { |
| 36 auto vals = (const T*)ptr; |
36 return SkNx(SkNx<N/2,T>::Load(vals), SkNx<N/2,T>::Load(vals+N/2)); | 37 return SkNx(SkNx<N/2,T>::Load(vals), SkNx<N/2,T>::Load(vals+N/2)); |
37 } | 38 } |
38 | 39 |
39 SkNx(T a, T b) : fLo(a), fHi(b) {
REQUIRE(N==2); } | 40 SkNx(T a, T b) : fLo(a), fHi(b) {
REQUIRE(N==2); } |
40 SkNx(T a, T b, T c, T d) : fLo(a,b), fHi(c,d) {
REQUIRE(N==4); } | 41 SkNx(T a, T b, T c, T d) : fLo(a,b), fHi(c,d) {
REQUIRE(N==4); } |
41 SkNx(T a, T b, T c, T d, T e, T f, T g, T h) : fLo(a,b,c,d), fHi(e,f,g,h) {
REQUIRE(N==8); } | 42 SkNx(T a, T b, T c, T d, T e, T f, T g, T h) : fLo(a,b,c,d), fHi(e,f,g,h) {
REQUIRE(N==8); } |
42 SkNx(T a, T b, T c, T d, T e, T f, T g, T h, | 43 SkNx(T a, T b, T c, T d, T e, T f, T g, T h, |
43 T i, T j, T k, T l, T m, T n, T o, T p) | 44 T i, T j, T k, T l, T m, T n, T o, T p) |
44 : fLo(a,b,c,d, e,f,g,h), fHi(i,j,k,l, m,n,o,p) { REQUIRE(N==16); } | 45 : fLo(a,b,c,d, e,f,g,h), fHi(i,j,k,l, m,n,o,p) { REQUIRE(N==16); } |
45 | 46 |
46 void store(T vals[N]) const { | 47 void store(void* ptr) const { |
| 48 auto vals = (T*)ptr; |
47 fLo.store(vals); | 49 fLo.store(vals); |
48 fHi.store(vals+N/2); | 50 fHi.store(vals+N/2); |
49 } | 51 } |
50 | 52 |
51 SkNx saturatedAdd(const SkNx& o) const { | 53 SkNx saturatedAdd(const SkNx& o) const { |
52 return SkNx(fLo.saturatedAdd(o.fLo), fHi.saturatedAdd(o.fHi)); | 54 return SkNx(fLo.saturatedAdd(o.fLo), fHi.saturatedAdd(o.fHi)); |
53 } | 55 } |
54 | 56 |
55 SkNx operator + (const SkNx& o) const { return SkNx(fLo + o.fLo, fHi + o.fHi
); } | 57 SkNx operator + (const SkNx& o) const { return SkNx(fLo + o.fLo, fHi + o.fHi
); } |
56 SkNx operator - (const SkNx& o) const { return SkNx(fLo - o.fLo, fHi - o.fHi
); } | 58 SkNx operator - (const SkNx& o) const { return SkNx(fLo - o.fLo, fHi - o.fHi
); } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 | 103 |
102 SkNx<N/2, T> fLo, fHi; | 104 SkNx<N/2, T> fLo, fHi; |
103 }; | 105 }; |
104 | 106 |
105 // Bottom out the default implementations with scalars when nothing's been speci
alized. | 107 // Bottom out the default implementations with scalars when nothing's been speci
alized. |
106 template <typename T> | 108 template <typename T> |
107 class SkNx<1,T> { | 109 class SkNx<1,T> { |
108 public: | 110 public: |
109 SkNx() {} | 111 SkNx() {} |
110 SkNx(T val) : fVal(val) {} | 112 SkNx(T val) : fVal(val) {} |
111 static SkNx Load(const T vals[1]) { return SkNx(vals[0]); } | 113 static SkNx Load(const void* ptr) { |
| 114 auto vals = (const T*)ptr; |
| 115 return SkNx(vals[0]); |
| 116 } |
112 | 117 |
113 void store(T vals[1]) const { vals[0] = fVal; } | 118 void store(void* ptr) const { |
| 119 auto vals = (T*) ptr; |
| 120 vals[0] = fVal; |
| 121 } |
114 | 122 |
115 SkNx saturatedAdd(const SkNx& o) const { | 123 SkNx saturatedAdd(const SkNx& o) const { |
116 SkASSERT((T)(~0) > 0); // TODO: support signed T | 124 SkASSERT((T)(~0) > 0); // TODO: support signed T |
117 T sum = fVal + o.fVal; | 125 T sum = fVal + o.fVal; |
118 return SkNx(sum < fVal ? (T)(~0) : sum); | 126 return SkNx(sum < fVal ? (T)(~0) : sum); |
119 } | 127 } |
120 | 128 |
121 SkNx operator + (const SkNx& o) const { return SkNx(fVal + o.fVal); } | 129 SkNx operator + (const SkNx& o) const { return SkNx(fVal + o.fVal); } |
122 SkNx operator - (const SkNx& o) const { return SkNx(fVal - o.fVal); } | 130 SkNx operator - (const SkNx& o) const { return SkNx(fVal - o.fVal); } |
123 SkNx operator * (const SkNx& o) const { return SkNx(fVal * o.fVal); } | 131 SkNx operator * (const SkNx& o) const { return SkNx(fVal * o.fVal); } |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 SkNx_cast<uint8_t>(b).store(p+ 4); | 250 SkNx_cast<uint8_t>(b).store(p+ 4); |
243 SkNx_cast<uint8_t>(c).store(p+ 8); | 251 SkNx_cast<uint8_t>(c).store(p+ 8); |
244 SkNx_cast<uint8_t>(d).store(p+12); | 252 SkNx_cast<uint8_t>(d).store(p+12); |
245 } | 253 } |
246 #endif | 254 #endif |
247 | 255 |
248 #undef REQUIRE | 256 #undef REQUIRE |
249 | 257 |
250 | 258 |
251 #endif//SkNx_DEFINED | 259 #endif//SkNx_DEFINED |
OLD | NEW |