| 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 |
| 11 | 11 |
| 12 #define SKNX_NO_SIMDx // Remove the x to disable SIMD for all SkNx types. | 12 #define SKNX_NO_SIMDx // Remove the x to disable SIMD for all SkNx types. |
| 13 | 13 |
| 14 | 14 |
| 15 #include "SkScalar.h" | 15 #include "SkScalar.h" |
| 16 #include "SkTypes.h" | 16 #include "SkTypes.h" |
| 17 #include <math.h> | 17 #include <math.h> |
| 18 #define REQUIRE(x) static_assert(x, #x) | 18 #define REQUIRE(x) static_assert(x, #x) |
| 19 | 19 |
| 20 // This file may be included multiple times by .cpp files with different flags,
leading | 20 // This file may be included multiple times by .cpp files with different flags,
leading |
| 21 // to different definitions. Usually that doesn't matter because it's all inlin
ed, but | 21 // to different definitions. Usually that doesn't matter because it's all inlin
ed, but |
| 22 // in Debug modes the compilers may not inline everything. So wrap everything i
n an | 22 // in Debug modes the compilers may not inline everything. So wrap everything i
n an |
| 23 // anonymous namespace to give each includer their own silo of this code (or the
linker | 23 // anonymous namespace to give each includer their own silo of this code (or the
linker |
| 24 // will probably pick one randomly for us, which is rarely correct). | 24 // will probably pick one randomly for us, which is rarely correct). |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 // The default implementations just fall back on a pair of size N/2. | 27 // The default implementations just fall back on a pair of size N/2. |
| 28 | 28 |
| 29 // SkNb is a _very_ minimal class representing a vector of bools returned by com
parison operators. | |
| 30 // We pass along the byte size of the compared types (Bytes) to help platform sp
ecializations. | |
| 31 template <int N, int Bytes> | |
| 32 class SkNb { | |
| 33 public: | |
| 34 SkNb() {} | |
| 35 SkNb(const SkNb<N/2, Bytes>& lo, const SkNb<N/2, Bytes>& hi) : fLo(lo), fHi(
hi) {} | |
| 36 | |
| 37 bool allTrue() const { return fLo.allTrue() && fHi.allTrue(); } | |
| 38 bool anyTrue() const { return fLo.anyTrue() || fHi.anyTrue(); } | |
| 39 | |
| 40 protected: | |
| 41 REQUIRE(0 == (N & (N-1))); | |
| 42 SkNb<N/2, Bytes> fLo, fHi; | |
| 43 }; | |
| 44 | |
| 45 template <int N, typename T> | 29 template <int N, typename T> |
| 46 class SkNi { | 30 class SkNi { |
| 47 public: | 31 public: |
| 48 SkNi() {} | 32 SkNi() {} |
| 49 SkNi(const SkNi<N/2, T>& lo, const SkNi<N/2, T>& hi) : fLo(lo), fHi(hi) {} | 33 SkNi(const SkNi<N/2, T>& lo, const SkNi<N/2, T>& hi) : fLo(lo), fHi(hi) {} |
| 50 explicit SkNi(T val) : fLo(val), fHi(val) {} | 34 explicit SkNi(T val) : fLo(val), fHi(val) {} |
| 51 static SkNi Load(const T vals[N]) { | 35 static SkNi Load(const T vals[N]) { |
| 52 return SkNi(SkNi<N/2,T>::Load(vals), SkNi<N/2,T>::Load(vals+N/2)); | 36 return SkNi(SkNi<N/2,T>::Load(vals), SkNi<N/2,T>::Load(vals+N/2)); |
| 53 } | 37 } |
| 54 | 38 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 71 SkNi operator + (const SkNi& o) const { return SkNi(fLo + o.fLo, fHi + o.fHi
); } | 55 SkNi operator + (const SkNi& o) const { return SkNi(fLo + o.fLo, fHi + o.fHi
); } |
| 72 SkNi operator - (const SkNi& o) const { return SkNi(fLo - o.fLo, fHi - o.fHi
); } | 56 SkNi operator - (const SkNi& o) const { return SkNi(fLo - o.fLo, fHi - o.fHi
); } |
| 73 SkNi operator * (const SkNi& o) const { return SkNi(fLo * o.fLo, fHi * o.fHi
); } | 57 SkNi operator * (const SkNi& o) const { return SkNi(fLo * o.fLo, fHi * o.fHi
); } |
| 74 | 58 |
| 75 SkNi operator << (int bits) const { return SkNi(fLo << bits, fHi << bits); } | 59 SkNi operator << (int bits) const { return SkNi(fLo << bits, fHi << bits); } |
| 76 SkNi operator >> (int bits) const { return SkNi(fLo >> bits, fHi >> bits); } | 60 SkNi operator >> (int bits) const { return SkNi(fLo >> bits, fHi >> bits); } |
| 77 | 61 |
| 78 static SkNi Min(const SkNi& a, const SkNi& b) { | 62 static SkNi Min(const SkNi& a, const SkNi& b) { |
| 79 return SkNi(SkNi<N/2, T>::Min(a.fLo, b.fLo), SkNi<N/2, T>::Min(a.fHi, b.
fHi)); | 63 return SkNi(SkNi<N/2, T>::Min(a.fLo, b.fLo), SkNi<N/2, T>::Min(a.fHi, b.
fHi)); |
| 80 } | 64 } |
| 81 | 65 SkNi operator < (const SkNi& o) const { return SkNi(fLo < o.fLo, fHi < o.fHi
); } |
| 82 // TODO: comparisons, max? | |
| 83 | 66 |
| 84 template <int k> T kth() const { | 67 template <int k> T kth() const { |
| 85 SkASSERT(0 <= k && k < N); | 68 SkASSERT(0 <= k && k < N); |
| 86 return k < N/2 ? fLo.template kth<k>() : fHi.template kth<k-N/2>(); | 69 return k < N/2 ? fLo.template kth<k>() : fHi.template kth<k-N/2>(); |
| 87 } | 70 } |
| 88 | 71 |
| 72 bool allTrue() const { return fLo.allTrue() && fHi.allTrue(); } |
| 73 bool anyTrue() const { return fLo.anyTrue() || fHi.anyTrue(); } |
| 74 SkNi thenElse(const SkNi& t, const SkNi& e) const { |
| 75 return SkNi(fLo.thenElse(t.fLo, e.fLo), fHi.thenElse(t.fHi, e.fHi)); |
| 76 } |
| 77 |
| 89 protected: | 78 protected: |
| 90 REQUIRE(0 == (N & (N-1))); | 79 REQUIRE(0 == (N & (N-1))); |
| 91 | 80 |
| 92 SkNi<N/2, T> fLo, fHi; | 81 SkNi<N/2, T> fLo, fHi; |
| 93 }; | 82 }; |
| 94 | 83 |
| 95 template <int N, typename T> | 84 template <int N, typename T> |
| 96 class SkNf { | 85 class SkNf { |
| 97 typedef SkNb<N, sizeof(T)> Nb; | |
| 98 | |
| 99 static int32_t MyNi(float); | 86 static int32_t MyNi(float); |
| 100 static int64_t MyNi(double); | 87 static int64_t MyNi(double); |
| 101 typedef SkNi<N, decltype(MyNi(T()))> Ni; | 88 typedef decltype(MyNi(T())) I; |
| 102 public: | 89 public: |
| 103 SkNf() {} | 90 SkNf() {} |
| 104 explicit SkNf(T val) : fLo(val), fHi(val) {} | 91 explicit SkNf(T val) : fLo(val), fHi(val) {} |
| 105 static SkNf Load(const T vals[N]) { | 92 static SkNf Load(const T vals[N]) { |
| 106 return SkNf(SkNf<N/2,T>::Load(vals), SkNf<N/2,T>::Load(vals+N/2)); | 93 return SkNf(SkNf<N/2,T>::Load(vals), SkNf<N/2,T>::Load(vals+N/2)); |
| 107 } | 94 } |
| 108 | 95 |
| 109 SkNf(T a, T b) : fLo(a), fHi(b) {
REQUIRE(N==2); } | 96 SkNf(T a, T b) : fLo(a), fHi(b) {
REQUIRE(N==2); } |
| 110 SkNf(T a, T b, T c, T d) : fLo(a,b), fHi(c,d) {
REQUIRE(N==4); } | 97 SkNf(T a, T b, T c, T d) : fLo(a,b), fHi(c,d) {
REQUIRE(N==4); } |
| 111 SkNf(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); } | 98 SkNf(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); } |
| 112 | 99 |
| 113 void store(T vals[N]) const { | 100 void store(T vals[N]) const { |
| 114 fLo.store(vals); | 101 fLo.store(vals); |
| 115 fHi.store(vals+N/2); | 102 fHi.store(vals+N/2); |
| 116 } | 103 } |
| 117 | 104 |
| 118 Ni castTrunc() const { return Ni(fLo.castTrunc(), fHi.castTrunc()); } | 105 SkNi<N,I> castTrunc() const { return SkNi<N,I>(fLo.castTrunc(), fHi.castTrun
c()); } |
| 119 | 106 |
| 120 SkNf operator + (const SkNf& o) const { return SkNf(fLo + o.fLo, fHi + o.fHi
); } | 107 SkNf operator + (const SkNf& o) const { return SkNf(fLo + o.fLo, fHi + o.fHi
); } |
| 121 SkNf operator - (const SkNf& o) const { return SkNf(fLo - o.fLo, fHi - o.fHi
); } | 108 SkNf operator - (const SkNf& o) const { return SkNf(fLo - o.fLo, fHi - o.fHi
); } |
| 122 SkNf operator * (const SkNf& o) const { return SkNf(fLo * o.fLo, fHi * o.fHi
); } | 109 SkNf operator * (const SkNf& o) const { return SkNf(fLo * o.fLo, fHi * o.fHi
); } |
| 123 SkNf operator / (const SkNf& o) const { return SkNf(fLo / o.fLo, fHi / o.fHi
); } | 110 SkNf operator / (const SkNf& o) const { return SkNf(fLo / o.fLo, fHi / o.fHi
); } |
| 124 | 111 |
| 125 Nb operator == (const SkNf& o) const { return Nb(fLo == o.fLo, fHi == o.fHi)
; } | 112 SkNf operator == (const SkNf& o) const { return SkNf(fLo == o.fLo, fHi == o.
fHi); } |
| 126 Nb operator != (const SkNf& o) const { return Nb(fLo != o.fLo, fHi != o.fHi)
; } | 113 SkNf operator != (const SkNf& o) const { return SkNf(fLo != o.fLo, fHi != o.
fHi); } |
| 127 Nb operator < (const SkNf& o) const { return Nb(fLo < o.fLo, fHi < o.fHi)
; } | 114 SkNf operator < (const SkNf& o) const { return SkNf(fLo < o.fLo, fHi < o.
fHi); } |
| 128 Nb operator > (const SkNf& o) const { return Nb(fLo > o.fLo, fHi > o.fHi)
; } | 115 SkNf operator > (const SkNf& o) const { return SkNf(fLo > o.fLo, fHi > o.
fHi); } |
| 129 Nb operator <= (const SkNf& o) const { return Nb(fLo <= o.fLo, fHi <= o.fHi)
; } | 116 SkNf operator <= (const SkNf& o) const { return SkNf(fLo <= o.fLo, fHi <= o.
fHi); } |
| 130 Nb operator >= (const SkNf& o) const { return Nb(fLo >= o.fLo, fHi >= o.fHi)
; } | 117 SkNf operator >= (const SkNf& o) const { return SkNf(fLo >= o.fLo, fHi >= o.
fHi); } |
| 131 | 118 |
| 132 static SkNf Min(const SkNf& l, const SkNf& r) { | 119 static SkNf Min(const SkNf& l, const SkNf& r) { |
| 133 return SkNf(SkNf<N/2,T>::Min(l.fLo, r.fLo), SkNf<N/2,T>::Min(l.fHi, r.fH
i)); | 120 return SkNf(SkNf<N/2,T>::Min(l.fLo, r.fLo), SkNf<N/2,T>::Min(l.fHi, r.fH
i)); |
| 134 } | 121 } |
| 135 static SkNf Max(const SkNf& l, const SkNf& r) { | 122 static SkNf Max(const SkNf& l, const SkNf& r) { |
| 136 return SkNf(SkNf<N/2,T>::Max(l.fLo, r.fLo), SkNf<N/2,T>::Max(l.fHi, r.fH
i)); | 123 return SkNf(SkNf<N/2,T>::Max(l.fLo, r.fLo), SkNf<N/2,T>::Max(l.fHi, r.fH
i)); |
| 137 } | 124 } |
| 138 | 125 |
| 139 SkNf sqrt() const { return SkNf(fLo. sqrt(), fHi. sqrt()); } | 126 SkNf sqrt() const { return SkNf(fLo. sqrt(), fHi. sqrt()); } |
| 140 | 127 |
| 141 // Generally, increasing precision, increasing cost. | 128 // Generally, increasing precision, increasing cost. |
| 142 SkNf rsqrt0() const { return SkNf(fLo.rsqrt0(), fHi.rsqrt0()); } | 129 SkNf rsqrt0() const { return SkNf(fLo.rsqrt0(), fHi.rsqrt0()); } |
| 143 SkNf rsqrt1() const { return SkNf(fLo.rsqrt1(), fHi.rsqrt1()); } | 130 SkNf rsqrt1() const { return SkNf(fLo.rsqrt1(), fHi.rsqrt1()); } |
| 144 SkNf rsqrt2() const { return SkNf(fLo.rsqrt2(), fHi.rsqrt2()); } | 131 SkNf rsqrt2() const { return SkNf(fLo.rsqrt2(), fHi.rsqrt2()); } |
| 145 | 132 |
| 146 SkNf invert() const { return SkNf(fLo. invert(), fHi. invert
()); } | 133 SkNf invert() const { return SkNf(fLo. invert(), fHi. invert
()); } |
| 147 SkNf approxInvert() const { return SkNf(fLo.approxInvert(), fHi.approxInvert
()); } | 134 SkNf approxInvert() const { return SkNf(fLo.approxInvert(), fHi.approxInvert
()); } |
| 148 | 135 |
| 149 template <int k> T kth() const { | 136 template <int k> T kth() const { |
| 150 SkASSERT(0 <= k && k < N); | 137 SkASSERT(0 <= k && k < N); |
| 151 return k < N/2 ? fLo.template kth<k>() : fHi.template kth<k-N/2>(); | 138 return k < N/2 ? fLo.template kth<k>() : fHi.template kth<k-N/2>(); |
| 152 } | 139 } |
| 153 | 140 |
| 141 bool allTrue() const { return fLo.allTrue() && fHi.allTrue(); } |
| 142 bool anyTrue() const { return fLo.anyTrue() || fHi.anyTrue(); } |
| 143 SkNf thenElse(const SkNf& t, const SkNf& e) const { |
| 144 return SkNf(fLo.thenElse(t.fLo, t.fHi), fHi.thenElse(t.fLo, t.fHi)); |
| 145 } |
| 146 |
| 154 protected: | 147 protected: |
| 155 REQUIRE(0 == (N & (N-1))); | 148 REQUIRE(0 == (N & (N-1))); |
| 156 SkNf(const SkNf<N/2, T>& lo, const SkNf<N/2, T>& hi) : fLo(lo), fHi(hi) {} | 149 SkNf(const SkNf<N/2, T>& lo, const SkNf<N/2, T>& hi) : fLo(lo), fHi(hi) {} |
| 157 | 150 |
| 158 SkNf<N/2, T> fLo, fHi; | 151 SkNf<N/2, T> fLo, fHi; |
| 159 }; | 152 }; |
| 160 | 153 |
| 161 | 154 |
| 162 // Bottom out the default implementations with scalars when nothing's been speci
alized. | 155 // Bottom out the default implementations with scalars when nothing's been speci
alized. |
| 163 | 156 |
| 164 template <int Bytes> | |
| 165 class SkNb<1, Bytes> { | |
| 166 public: | |
| 167 SkNb() {} | |
| 168 explicit SkNb(bool val) : fVal(val) {} | |
| 169 bool allTrue() const { return fVal; } | |
| 170 bool anyTrue() const { return fVal; } | |
| 171 protected: | |
| 172 bool fVal; | |
| 173 }; | |
| 174 | |
| 175 template <typename T> | 157 template <typename T> |
| 176 class SkNi<1,T> { | 158 class SkNi<1,T> { |
| 177 public: | 159 public: |
| 178 SkNi() {} | 160 SkNi() {} |
| 179 explicit SkNi(T val) : fVal(val) {} | 161 explicit SkNi(T val) : fVal(val) {} |
| 180 static SkNi Load(const T vals[1]) { return SkNi(vals[0]); } | 162 static SkNi Load(const T vals[1]) { return SkNi(vals[0]); } |
| 181 | 163 |
| 182 void store(T vals[1]) const { vals[0] = fVal; } | 164 void store(T vals[1]) const { vals[0] = fVal; } |
| 183 | 165 |
| 184 SkNi saturatedAdd(const SkNi& o) const { | 166 SkNi saturatedAdd(const SkNi& o) const { |
| 185 SkASSERT((T)(~0) > 0); // TODO: support signed T | 167 SkASSERT((T)(~0) > 0); // TODO: support signed T |
| 186 T sum = fVal + o.fVal; | 168 T sum = fVal + o.fVal; |
| 187 return SkNi(sum < fVal ? (T)(~0) : sum); | 169 return SkNi(sum < fVal ? (T)(~0) : sum); |
| 188 } | 170 } |
| 189 | 171 |
| 190 SkNi operator + (const SkNi& o) const { return SkNi(fVal + o.fVal); } | 172 SkNi operator + (const SkNi& o) const { return SkNi(fVal + o.fVal); } |
| 191 SkNi operator - (const SkNi& o) const { return SkNi(fVal - o.fVal); } | 173 SkNi operator - (const SkNi& o) const { return SkNi(fVal - o.fVal); } |
| 192 SkNi operator * (const SkNi& o) const { return SkNi(fVal * o.fVal); } | 174 SkNi operator * (const SkNi& o) const { return SkNi(fVal * o.fVal); } |
| 193 | 175 |
| 194 SkNi operator << (int bits) const { return SkNi(fVal << bits); } | 176 SkNi operator << (int bits) const { return SkNi(fVal << bits); } |
| 195 SkNi operator >> (int bits) const { return SkNi(fVal >> bits); } | 177 SkNi operator >> (int bits) const { return SkNi(fVal >> bits); } |
| 196 | 178 |
| 197 static SkNi Min(const SkNi& a, const SkNi& b) { return SkNi(SkTMin(a.fVal, b
.fVal)); } | 179 static SkNi Min(const SkNi& a, const SkNi& b) { return SkNi(SkTMin(a.fVal, b
.fVal)); } |
| 180 SkNi operator <(const SkNi& o) const { return SkNi(fVal < o.fVal); } |
| 198 | 181 |
| 199 template <int k> T kth() const { | 182 template <int k> T kth() const { |
| 200 SkASSERT(0 == k); | 183 SkASSERT(0 == k); |
| 201 return fVal; | 184 return fVal; |
| 202 } | 185 } |
| 203 | 186 |
| 187 bool allTrue() const { return fVal; } |
| 188 bool anyTrue() const { return fVal; } |
| 189 SkNi thenElse(const SkNi& t, const SkNi& e) const { return fVal ? t : e; } |
| 190 |
| 204 protected: | 191 protected: |
| 205 T fVal; | 192 T fVal; |
| 206 }; | 193 }; |
| 207 | 194 |
| 208 template <typename T> | 195 template <typename T> |
| 209 class SkNf<1,T> { | 196 class SkNf<1,T> { |
| 210 typedef SkNb<1, sizeof(T)> Nb; | |
| 211 | |
| 212 static int32_t MyNi(float); | 197 static int32_t MyNi(float); |
| 213 static int64_t MyNi(double); | 198 static int64_t MyNi(double); |
| 214 typedef SkNi<1, decltype(MyNi(T()))> Ni; | 199 typedef decltype(MyNi(T())) I; |
| 215 public: | 200 public: |
| 216 SkNf() {} | 201 SkNf() {} |
| 217 explicit SkNf(T val) : fVal(val) {} | 202 explicit SkNf(T val) : fVal(val) {} |
| 218 static SkNf Load(const T vals[1]) { return SkNf(vals[0]); } | 203 static SkNf Load(const T vals[1]) { return SkNf(vals[0]); } |
| 219 | 204 |
| 220 void store(T vals[1]) const { vals[0] = fVal; } | 205 void store(T vals[1]) const { vals[0] = fVal; } |
| 221 | 206 |
| 222 Ni castTrunc() const { return Ni(fVal); } | 207 SkNi<1,I> castTrunc() const { return SkNi<1,I>(fVal); } |
| 223 | 208 |
| 224 SkNf operator + (const SkNf& o) const { return SkNf(fVal + o.fVal); } | 209 SkNf operator + (const SkNf& o) const { return SkNf(fVal + o.fVal); } |
| 225 SkNf operator - (const SkNf& o) const { return SkNf(fVal - o.fVal); } | 210 SkNf operator - (const SkNf& o) const { return SkNf(fVal - o.fVal); } |
| 226 SkNf operator * (const SkNf& o) const { return SkNf(fVal * o.fVal); } | 211 SkNf operator * (const SkNf& o) const { return SkNf(fVal * o.fVal); } |
| 227 SkNf operator / (const SkNf& o) const { return SkNf(fVal / o.fVal); } | 212 SkNf operator / (const SkNf& o) const { return SkNf(fVal / o.fVal); } |
| 228 | 213 |
| 229 Nb operator == (const SkNf& o) const { return Nb(fVal == o.fVal); } | 214 SkNf operator == (const SkNf& o) const { return SkNf(fVal == o.fVal); } |
| 230 Nb operator != (const SkNf& o) const { return Nb(fVal != o.fVal); } | 215 SkNf operator != (const SkNf& o) const { return SkNf(fVal != o.fVal); } |
| 231 Nb operator < (const SkNf& o) const { return Nb(fVal < o.fVal); } | 216 SkNf operator < (const SkNf& o) const { return SkNf(fVal < o.fVal); } |
| 232 Nb operator > (const SkNf& o) const { return Nb(fVal > o.fVal); } | 217 SkNf operator > (const SkNf& o) const { return SkNf(fVal > o.fVal); } |
| 233 Nb operator <= (const SkNf& o) const { return Nb(fVal <= o.fVal); } | 218 SkNf operator <= (const SkNf& o) const { return SkNf(fVal <= o.fVal); } |
| 234 Nb operator >= (const SkNf& o) const { return Nb(fVal >= o.fVal); } | 219 SkNf operator >= (const SkNf& o) const { return SkNf(fVal >= o.fVal); } |
| 235 | 220 |
| 236 static SkNf Min(const SkNf& l, const SkNf& r) { return SkNf(SkTMin(l.fVal, r
.fVal)); } | 221 static SkNf Min(const SkNf& l, const SkNf& r) { return SkNf(SkTMin(l.fVal, r
.fVal)); } |
| 237 static SkNf Max(const SkNf& l, const SkNf& r) { return SkNf(SkTMax(l.fVal, r
.fVal)); } | 222 static SkNf Max(const SkNf& l, const SkNf& r) { return SkNf(SkTMax(l.fVal, r
.fVal)); } |
| 238 | 223 |
| 239 SkNf sqrt() const { return SkNf(Sqrt(fVal)); } | 224 SkNf sqrt() const { return SkNf(Sqrt(fVal)); } |
| 240 SkNf rsqrt0() const { return SkNf((T)1 / Sqrt(fVal)); } | 225 SkNf rsqrt0() const { return SkNf((T)1 / Sqrt(fVal)); } |
| 241 SkNf rsqrt1() const { return this->rsqrt0(); } | 226 SkNf rsqrt1() const { return this->rsqrt0(); } |
| 242 SkNf rsqrt2() const { return this->rsqrt1(); } | 227 SkNf rsqrt2() const { return this->rsqrt1(); } |
| 243 | 228 |
| 244 SkNf invert() const { return SkNf((T)1 / fVal); } | 229 SkNf invert() const { return SkNf((T)1 / fVal); } |
| 245 SkNf approxInvert() const { return this->invert(); } | 230 SkNf approxInvert() const { return this->invert(); } |
| 246 | 231 |
| 247 template <int k> T kth() const { | 232 template <int k> T kth() const { |
| 248 SkASSERT(k == 0); | 233 SkASSERT(k == 0); |
| 249 return fVal; | 234 return fVal; |
| 250 } | 235 } |
| 251 | 236 |
| 237 bool allTrue() const { return this->pun(); } |
| 238 bool anyTrue() const { return this->pun(); } |
| 239 SkNf thenElse(const SkNf& t, const SkNf& e) const { return this->pun() ? t :
e; } |
| 240 |
| 252 protected: | 241 protected: |
| 253 // We do double sqrts natively, or via floats for any other type. | 242 // We do double sqrts natively, or via floats for any other type. |
| 254 template <typename U> | 243 template <typename U> |
| 255 static U Sqrt(U val) { return (U) ::sqrtf((float)val); } | 244 static U Sqrt(U val) { return (U) ::sqrtf((float)val); } |
| 256 static double Sqrt(double val) { return ::sqrt ( val); } | 245 static double Sqrt(double val) { return ::sqrt ( val); } |
| 257 | 246 |
| 247 I pun() const { |
| 248 union { T f; I i; } pun = { fVal }; |
| 249 return pun.i; |
| 250 } |
| 251 |
| 258 T fVal; | 252 T fVal; |
| 259 }; | 253 }; |
| 260 | 254 |
| 261 } // namespace | 255 } // namespace |
| 262 | 256 |
| 263 // Include platform specific specializations if available. | 257 // Include platform specific specializations if available. |
| 264 #ifndef SKNX_NO_SIMD | 258 #ifndef SKNX_NO_SIMD |
| 265 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 | 259 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 |
| 266 #include "../opts/SkNx_sse.h" | 260 #include "../opts/SkNx_sse.h" |
| 267 #elif defined(SK_ARM_HAS_NEON) | 261 #elif defined(SK_ARM_HAS_NEON) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 282 typedef SkNi<4, uint16_t> Sk4h; | 276 typedef SkNi<4, uint16_t> Sk4h; |
| 283 typedef SkNi<8, uint16_t> Sk8h; | 277 typedef SkNi<8, uint16_t> Sk8h; |
| 284 typedef SkNi<16, uint16_t> Sk16h; | 278 typedef SkNi<16, uint16_t> Sk16h; |
| 285 | 279 |
| 286 typedef SkNi<16, uint8_t> Sk16b; | 280 typedef SkNi<16, uint8_t> Sk16b; |
| 287 | 281 |
| 288 typedef SkNi<4, int32_t> Sk4i; | 282 typedef SkNi<4, int32_t> Sk4i; |
| 289 typedef SkNi<4, uint32_t> Sk4u; | 283 typedef SkNi<4, uint32_t> Sk4u; |
| 290 | 284 |
| 291 #endif//SkNx_DEFINED | 285 #endif//SkNx_DEFINED |
| OLD | NEW |