| 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 12 matching lines...) Expand all Loading... |
| 23 // We pass along the byte size of the compared types (Bytes) to help platform sp
ecializations. | 23 // We pass along the byte size of the compared types (Bytes) to help platform sp
ecializations. |
| 24 template <int N, int Bytes> | 24 template <int N, int Bytes> |
| 25 class SkNb { | 25 class SkNb { |
| 26 public: | 26 public: |
| 27 SkNb() {} | 27 SkNb() {} |
| 28 SkNb(const SkNb<N/2, Bytes>& lo, const SkNb<N/2, Bytes>& hi) : fLo(lo), fHi(
hi) {} | 28 SkNb(const SkNb<N/2, Bytes>& lo, const SkNb<N/2, Bytes>& hi) : fLo(lo), fHi(
hi) {} |
| 29 | 29 |
| 30 bool allTrue() const { return fLo.allTrue() && fHi.allTrue(); } | 30 bool allTrue() const { return fLo.allTrue() && fHi.allTrue(); } |
| 31 bool anyTrue() const { return fLo.anyTrue() || fHi.anyTrue(); } | 31 bool anyTrue() const { return fLo.anyTrue() || fHi.anyTrue(); } |
| 32 | 32 |
| 33 private: | 33 protected: |
| 34 REQUIRE(0 == (N & (N-1))); | 34 REQUIRE(0 == (N & (N-1))); |
| 35 SkNb<N/2, Bytes> fLo, fHi; | 35 SkNb<N/2, Bytes> fLo, fHi; |
| 36 }; | 36 }; |
| 37 | 37 |
| 38 template <int N, typename T> | 38 template <int N, typename T> |
| 39 class SkNi { | 39 class SkNi { |
| 40 public: | 40 public: |
| 41 SkNi() {} | 41 SkNi() {} |
| 42 SkNi(const SkNi<N/2, T>& lo, const SkNi<N/2, T>& hi) : fLo(lo), fHi(hi) {} | 42 SkNi(const SkNi<N/2, T>& lo, const SkNi<N/2, T>& hi) : fLo(lo), fHi(hi) {} |
| 43 explicit SkNi(T val) : fLo(val), fHi(val) {} | 43 explicit SkNi(T val) : fLo(val), fHi(val) {} |
| 44 static SkNi Load(const T vals[N]) { | 44 static SkNi Load(const T vals[N]) { |
| 45 return SkNi(SkNi<N/2,T>::Load(vals), SkNi<N/2,T>::Load(vals+N/2)); | 45 return SkNi(SkNi<N/2,T>::Load(vals), SkNi<N/2,T>::Load(vals+N/2)); |
| 46 } | 46 } |
| 47 | 47 |
| 48 SkNi(T a, T b) : fLo(a), fHi(b) {
REQUIRE(N==2); } | 48 SkNi(T a, T b) : fLo(a), fHi(b) {
REQUIRE(N==2); } |
| 49 SkNi(T a, T b, T c, T d) : fLo(a,b), fHi(c,d) {
REQUIRE(N==4); } | 49 SkNi(T a, T b, T c, T d) : fLo(a,b), fHi(c,d) {
REQUIRE(N==4); } |
| 50 SkNi(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); } | 50 SkNi(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); } |
| 51 SkNi(T a, T b, T c, T d, T e, T f, T g, T h, |
| 52 T i, T j, T k, T l, T m, T n, T o, T p) |
| 53 : fLo(a,b,c,d, e,f,g,h), fHi(i,j,k,l, m,n,o,p) { REQUIRE(N==16); } |
| 51 | 54 |
| 52 void store(T vals[N]) const { | 55 void store(T vals[N]) const { |
| 53 fLo.store(vals); | 56 fLo.store(vals); |
| 54 fHi.store(vals+N/2); | 57 fHi.store(vals+N/2); |
| 55 } | 58 } |
| 56 | 59 |
| 57 SkNi operator + (const SkNi& o) const { return SkNi(fLo + o.fLo, fHi + o.fHi
); } | 60 SkNi operator + (const SkNi& o) const { return SkNi(fLo + o.fLo, fHi + o.fHi
); } |
| 58 SkNi operator - (const SkNi& o) const { return SkNi(fLo - o.fLo, fHi - o.fHi
); } | 61 SkNi operator - (const SkNi& o) const { return SkNi(fLo - o.fLo, fHi - o.fHi
); } |
| 59 SkNi operator * (const SkNi& o) const { return SkNi(fLo * o.fLo, fHi * o.fHi
); } | 62 SkNi operator * (const SkNi& o) const { return SkNi(fLo * o.fLo, fHi * o.fHi
); } |
| 60 | 63 |
| 61 SkNi operator << (int bits) const { return SkNi(fLo << bits, fHi << bits); } | 64 SkNi operator << (int bits) const { return SkNi(fLo << bits, fHi << bits); } |
| 62 SkNi operator >> (int bits) const { return SkNi(fLo >> bits, fHi >> bits); } | 65 SkNi operator >> (int bits) const { return SkNi(fLo >> bits, fHi >> bits); } |
| 63 | 66 |
| 64 // TODO: comparisons, min, max? | 67 // TODO: comparisons, min, max? |
| 65 | 68 |
| 66 template <int k> T kth() const { | 69 template <int k> T kth() const { |
| 67 SkASSERT(0 <= k && k < N); | 70 SkASSERT(0 <= k && k < N); |
| 68 return k < N/2 ? fLo.template kth<k>() : fHi.template kth<k-N/2>(); | 71 return k < N/2 ? fLo.template kth<k>() : fHi.template kth<k-N/2>(); |
| 69 } | 72 } |
| 70 | 73 |
| 71 private: | 74 protected: |
| 72 REQUIRE(0 == (N & (N-1))); | 75 REQUIRE(0 == (N & (N-1))); |
| 73 | 76 |
| 74 SkNi<N/2, T> fLo, fHi; | 77 SkNi<N/2, T> fLo, fHi; |
| 75 }; | 78 }; |
| 76 | 79 |
| 77 template <int N, typename T> | 80 template <int N, typename T> |
| 78 class SkNf { | 81 class SkNf { |
| 79 typedef SkNb<N, sizeof(T)> Nb; | 82 typedef SkNb<N, sizeof(T)> Nb; |
| 80 | 83 |
| 81 static int32_t MyNi(float); | 84 static int32_t MyNi(float); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 SkNf rsqrt2() const { return SkNf(fLo.rsqrt2(), fHi.rsqrt2()); } | 129 SkNf rsqrt2() const { return SkNf(fLo.rsqrt2(), fHi.rsqrt2()); } |
| 127 | 130 |
| 128 SkNf invert() const { return SkNf(fLo. invert(), fHi. invert
()); } | 131 SkNf invert() const { return SkNf(fLo. invert(), fHi. invert
()); } |
| 129 SkNf approxInvert() const { return SkNf(fLo.approxInvert(), fHi.approxInvert
()); } | 132 SkNf approxInvert() const { return SkNf(fLo.approxInvert(), fHi.approxInvert
()); } |
| 130 | 133 |
| 131 template <int k> T kth() const { | 134 template <int k> T kth() const { |
| 132 SkASSERT(0 <= k && k < N); | 135 SkASSERT(0 <= k && k < N); |
| 133 return k < N/2 ? fLo.template kth<k>() : fHi.template kth<k-N/2>(); | 136 return k < N/2 ? fLo.template kth<k>() : fHi.template kth<k-N/2>(); |
| 134 } | 137 } |
| 135 | 138 |
| 136 private: | 139 protected: |
| 137 REQUIRE(0 == (N & (N-1))); | 140 REQUIRE(0 == (N & (N-1))); |
| 138 SkNf(const SkNf<N/2, T>& lo, const SkNf<N/2, T>& hi) : fLo(lo), fHi(hi) {} | 141 SkNf(const SkNf<N/2, T>& lo, const SkNf<N/2, T>& hi) : fLo(lo), fHi(hi) {} |
| 139 | 142 |
| 140 SkNf<N/2, T> fLo, fHi; | 143 SkNf<N/2, T> fLo, fHi; |
| 141 }; | 144 }; |
| 142 | 145 |
| 143 | 146 |
| 144 // Bottom out the default implementations with scalars when nothing's been speci
alized. | 147 // Bottom out the default implementations with scalars when nothing's been speci
alized. |
| 145 | 148 |
| 146 template <int Bytes> | 149 template <int Bytes> |
| 147 class SkNb<1, Bytes> { | 150 class SkNb<1, Bytes> { |
| 148 public: | 151 public: |
| 149 SkNb() {} | 152 SkNb() {} |
| 150 explicit SkNb(bool val) : fVal(val) {} | 153 explicit SkNb(bool val) : fVal(val) {} |
| 151 bool allTrue() const { return fVal; } | 154 bool allTrue() const { return fVal; } |
| 152 bool anyTrue() const { return fVal; } | 155 bool anyTrue() const { return fVal; } |
| 153 private: | 156 protected: |
| 154 bool fVal; | 157 bool fVal; |
| 155 }; | 158 }; |
| 156 | 159 |
| 157 template <typename T> | 160 template <typename T> |
| 158 class SkNi<1,T> { | 161 class SkNi<1,T> { |
| 159 public: | 162 public: |
| 160 SkNi() {} | 163 SkNi() {} |
| 161 explicit SkNi(T val) : fVal(val) {} | 164 explicit SkNi(T val) : fVal(val) {} |
| 162 static SkNi Load(const T vals[1]) { return SkNi(vals[0]); } | 165 static SkNi Load(const T vals[1]) { return SkNi(vals[0]); } |
| 163 | 166 |
| 164 void store(T vals[1]) const { vals[0] = fVal; } | 167 void store(T vals[1]) const { vals[0] = fVal; } |
| 165 | 168 |
| 166 SkNi operator + (const SkNi& o) const { return SkNi(fVal + o.fVal); } | 169 SkNi operator + (const SkNi& o) const { return SkNi(fVal + o.fVal); } |
| 167 SkNi operator - (const SkNi& o) const { return SkNi(fVal - o.fVal); } | 170 SkNi operator - (const SkNi& o) const { return SkNi(fVal - o.fVal); } |
| 168 SkNi operator * (const SkNi& o) const { return SkNi(fVal * o.fVal); } | 171 SkNi operator * (const SkNi& o) const { return SkNi(fVal * o.fVal); } |
| 169 | 172 |
| 170 SkNi operator << (int bits) const { return SkNi(fVal << bits); } | 173 SkNi operator << (int bits) const { return SkNi(fVal << bits); } |
| 171 SkNi operator >> (int bits) const { return SkNi(fVal >> bits); } | 174 SkNi operator >> (int bits) const { return SkNi(fVal >> bits); } |
| 172 | 175 |
| 173 template <int k> T kth() const { | 176 template <int k> T kth() const { |
| 174 SkASSERT(0 == k); | 177 SkASSERT(0 == k); |
| 175 return fVal; | 178 return fVal; |
| 176 } | 179 } |
| 177 | 180 |
| 178 private: | 181 protected: |
| 179 T fVal; | 182 T fVal; |
| 180 }; | 183 }; |
| 181 | 184 |
| 182 template <typename T> | 185 template <typename T> |
| 183 class SkNf<1,T> { | 186 class SkNf<1,T> { |
| 184 typedef SkNb<1, sizeof(T)> Nb; | 187 typedef SkNb<1, sizeof(T)> Nb; |
| 185 | 188 |
| 186 static int32_t MyNi(float); | 189 static int32_t MyNi(float); |
| 187 static int64_t MyNi(double); | 190 static int64_t MyNi(double); |
| 188 typedef SkNi<1, decltype(MyNi(T()))> Ni; | 191 typedef SkNi<1, decltype(MyNi(T()))> Ni; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 216 SkNf rsqrt2() const { return this->rsqrt1(); } | 219 SkNf rsqrt2() const { return this->rsqrt1(); } |
| 217 | 220 |
| 218 SkNf invert() const { return SkNf((T)1 / fVal); } | 221 SkNf invert() const { return SkNf((T)1 / fVal); } |
| 219 SkNf approxInvert() const { return this->invert(); } | 222 SkNf approxInvert() const { return this->invert(); } |
| 220 | 223 |
| 221 template <int k> T kth() const { | 224 template <int k> T kth() const { |
| 222 SkASSERT(k == 0); | 225 SkASSERT(k == 0); |
| 223 return fVal; | 226 return fVal; |
| 224 } | 227 } |
| 225 | 228 |
| 226 private: | 229 protected: |
| 227 // We do double sqrts natively, or via floats for any other type. | 230 // We do double sqrts natively, or via floats for any other type. |
| 228 template <typename U> | 231 template <typename U> |
| 229 static U Sqrt(U val) { return (U) ::sqrtf((float)val); } | 232 static U Sqrt(U val) { return (U) ::sqrtf((float)val); } |
| 230 static double Sqrt(double val) { return ::sqrt ( val); } | 233 static double Sqrt(double val) { return ::sqrt ( val); } |
| 231 | 234 |
| 232 T fVal; | 235 T fVal; |
| 233 }; | 236 }; |
| 234 | 237 |
| 235 | 238 |
| 236 // Generic syntax sugar that should work equally well for all implementations. | 239 // Generic syntax sugar that should work equally well for all implementations. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 256 #undef REQUIRE | 259 #undef REQUIRE |
| 257 | 260 |
| 258 typedef SkNf<2, float> Sk2f; | 261 typedef SkNf<2, float> Sk2f; |
| 259 typedef SkNf<2, double> Sk2d; | 262 typedef SkNf<2, double> Sk2d; |
| 260 typedef SkNf<2, SkScalar> Sk2s; | 263 typedef SkNf<2, SkScalar> Sk2s; |
| 261 | 264 |
| 262 typedef SkNf<4, float> Sk4f; | 265 typedef SkNf<4, float> Sk4f; |
| 263 typedef SkNf<4, double> Sk4d; | 266 typedef SkNf<4, double> Sk4d; |
| 264 typedef SkNf<4, SkScalar> Sk4s; | 267 typedef SkNf<4, SkScalar> Sk4s; |
| 265 | 268 |
| 266 typedef SkNi<4, uint16_t> Sk4h; | 269 typedef SkNi<4, uint16_t> Sk4h; |
| 267 typedef SkNi<8, uint16_t> Sk8h; | 270 typedef SkNi<8, uint16_t> Sk8h; |
| 271 typedef SkNi<16, uint16_t> Sk16h; |
| 268 | 272 |
| 269 typedef SkNi<4, int> Sk4i; | 273 typedef SkNi<16, uint8_t> Sk16b; |
| 274 |
| 275 typedef SkNi<4, int32_t> Sk4i; |
| 276 typedef SkNi<4, uint32_t> Sk4u; |
| 270 | 277 |
| 271 #endif//SkNx_DEFINED | 278 #endif//SkNx_DEFINED |
| OLD | NEW |