Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(967)

Side by Side Diff: src/core/SkNx.h

Issue 1048593002: Refactor Sk2x<T> + Sk4x<T> into SkNf<N,T> and SkNi<N,T> (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: This is actually faster Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkMatrix.cpp ('k') | src/core/SkPMFloat.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #define SKNX_NO_SIMDx // Remove the x to disable SIMD in Sk2x and Sk4x. 11
12 #define SKNX_NO_SIMDx // Remove the x to disable SIMD for all SkNx types.
13
14
15 #include "SkScalar.h"
16 #include "SkTypes.h"
17 #include <math.h>
18 #define REQUIRE(x) static_assert(x, #x)
19
20 // The default implementations of SkNi<N,T> and SkNf<N,T> just fall back on a pa ir of size N/2.
21 template <int N, typename T>
22 class SkNi {
23 public:
24 // For now SkNi is a _very_ minimal sketch just to support comparison operat ors on SkNf.
25 SkNi() {}
26 SkNi(const SkNi<N/2, T>& lo, const SkNi<N/2, T>& hi) : fLo(lo), fHi(hi) {}
27 bool allTrue() const { return fLo.allTrue() && fHi.allTrue(); }
28 bool anyTrue() const { return fLo.anyTrue() || fHi.anyTrue(); }
29
30 private:
31 REQUIRE(0 == (N & (N-1)));
32 SkNi<N/2, T> fLo, fHi;
33 };
34
35 template <int N, typename T>
36 class SkNf {
37 static SkNi<N,int32_t> ToNi(float);
38 static SkNi<N,int64_t> ToNi(double);
39 typedef decltype(ToNi(T())) Ni;
40 public:
41 SkNf() {}
42 explicit SkNf(T val) : fLo(val), fHi(val) {}
43 static SkNf Load(const T vals[N]) {
44 return SkNf(SkNf<N/2,T>::Load(vals), SkNf<N/2,T>::Load(vals+N/2));
45 }
46
47 SkNf(T a, T b) : fLo(a), fHi(b) { REQUIRE(N==2); }
48 SkNf(T a, T b, T c, T d) : fLo(a,b), fHi(c,d) { REQUIRE(N==4); }
49 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); }
50
51 void store(T vals[N]) const {
52 fLo.store(vals);
53 fHi.store(vals+N/2);
54 }
55
56 SkNf operator + (const SkNf& o) const { return SkNf(fLo + o.fLo, fHi + o.fHi ); }
57 SkNf operator - (const SkNf& o) const { return SkNf(fLo - o.fLo, fHi - o.fHi ); }
58 SkNf operator * (const SkNf& o) const { return SkNf(fLo * o.fLo, fHi * o.fHi ); }
59 SkNf operator / (const SkNf& o) const { return SkNf(fLo / o.fLo, fHi / o.fHi ); }
60
61 Ni operator == (const SkNf& o) const { return Ni(fLo == o.fLo, fHi == o.fHi) ; }
62 Ni operator != (const SkNf& o) const { return Ni(fLo != o.fLo, fHi != o.fHi) ; }
63 Ni operator < (const SkNf& o) const { return Ni(fLo < o.fLo, fHi < o.fHi) ; }
64 Ni operator > (const SkNf& o) const { return Ni(fLo > o.fLo, fHi > o.fHi) ; }
65 Ni operator <= (const SkNf& o) const { return Ni(fLo <= o.fLo, fHi <= o.fHi) ; }
66 Ni operator >= (const SkNf& o) const { return Ni(fLo >= o.fLo, fHi >= o.fHi) ; }
67
68 static SkNf Min(const SkNf& l, const SkNf& r) {
69 return SkNf(SkNf<N/2,T>::Min(l.fLo, r.fLo), SkNf<N/2,T>::Min(l.fHi, r.fH i));
70 }
71 static SkNf Max(const SkNf& l, const SkNf& r) {
72 return SkNf(SkNf<N/2,T>::Max(l.fLo, r.fLo), SkNf<N/2,T>::Max(l.fHi, r.fH i));
73 }
74
75 SkNf sqrt() const { return SkNf(fLo. sqrt(), fHi. sqrt()); }
76 SkNf rsqrt() const { return SkNf(fLo.rsqrt(), fHi.rsqrt()); }
77
78 SkNf invert() const { return SkNf(fLo. invert(), fHi. invert ()); }
79 SkNf approxInvert() const { return SkNf(fLo.approxInvert(), fHi.approxInvert ()); }
80
81 T operator[] (int k) const {
82 SkASSERT(0 <= k && k < N);
83 return k < N/2 ? fLo[k] : fHi[k-N/2];
84 }
85
86 private:
87 REQUIRE(0 == (N & (N-1)));
88 SkNf(const SkNf<N/2, T>& lo, const SkNf<N/2, T>& hi) : fLo(lo), fHi(hi) {}
89
90 SkNf<N/2, T> fLo, fHi;
91 };
92
93
94 // Bottom out the default implementation with scalars when nothing's been specia lized.
95 template <typename T>
96 class SkNi<1,T> {
97 public:
98 SkNi() {}
99 explicit SkNi(T val) : fVal(val) {}
100 bool allTrue() const { return (bool)fVal; }
101 bool anyTrue() const { return (bool)fVal; }
102
103 private:
104 T fVal;
105 };
106
107 template <typename T>
108 class SkNf<1,T> {
109 static SkNi<1,int32_t> ToNi(float);
110 static SkNi<1,int64_t> ToNi(double);
111 typedef decltype(ToNi(T())) Ni;
112 public:
113 SkNf() {}
114 explicit SkNf(T val) : fVal(val) {}
115 static SkNf Load(const T vals[1]) { return SkNf(vals[0]); }
116
117 void store(T vals[1]) const { vals[0] = fVal; }
118
119 SkNf operator + (const SkNf& o) const { return SkNf(fVal + o.fVal); }
120 SkNf operator - (const SkNf& o) const { return SkNf(fVal - o.fVal); }
121 SkNf operator * (const SkNf& o) const { return SkNf(fVal * o.fVal); }
122 SkNf operator / (const SkNf& o) const { return SkNf(fVal / o.fVal); }
123
124 Ni operator == (const SkNf& o) const { return Ni(fVal == o.fVal); }
125 Ni operator != (const SkNf& o) const { return Ni(fVal != o.fVal); }
126 Ni operator < (const SkNf& o) const { return Ni(fVal < o.fVal); }
127 Ni operator > (const SkNf& o) const { return Ni(fVal > o.fVal); }
128 Ni operator <= (const SkNf& o) const { return Ni(fVal <= o.fVal); }
129 Ni operator >= (const SkNf& o) const { return Ni(fVal >= o.fVal); }
130
131 static SkNf Min(const SkNf& l, const SkNf& r) { return SkNf(SkTMin(l.fVal, r .fVal)); }
132 static SkNf Max(const SkNf& l, const SkNf& r) { return SkNf(SkTMax(l.fVal, r .fVal)); }
133
134 SkNf sqrt() const { return SkNf(Sqrt(fVal)); }
135 SkNf rsqrt() const { return SkNf((T)1 / Sqrt(fVal)); }
136
137 SkNf invert() const { return SkNf((T)1 / fVal); }
138 SkNf approxInvert() const { return this->invert(); }
139
140 T operator[] (int SkDEBUGCODE(k)) const {
141 SkASSERT(k == 0);
142 return fVal;
143 }
144
145 private:
146 // We do double sqrts natively, or via floats for any other type.
147 template <typename U>
148 static U Sqrt(U val) { return (U) ::sqrtf((float)val); }
149 static double Sqrt(double val) { return ::sqrt ( val); }
150
151 T fVal;
152 };
153
154
155 // Generic syntax sugar that should work equally well for all SkNi and SkNf impl ementations.
156 template <typename SkNx> SkNx operator - (const SkNx& l) { return SkNx((decltype (l[0]))0) - l; }
157
158 template <typename SkNx> SkNx& operator += (SkNx& l, const SkNx& r) { return (l = l + r); }
159 template <typename SkNx> SkNx& operator -= (SkNx& l, const SkNx& r) { return (l = l - r); }
160 template <typename SkNx> SkNx& operator *= (SkNx& l, const SkNx& r) { return (l = l * r); }
161 template <typename SkNx> SkNx& operator /= (SkNx& l, const SkNx& r) { return (l = l / r); }
162
163
164 // Include platform specific specializations if available.
165 #ifndef SKNX_NO_SIMD
166 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
167 #include "../opts/SkNx_sse.h"
168 #elif defined(SK_ARM_HAS_NEON)
169 #include "../opts/SkNx_neon.h"
170 #endif
171 #endif
172
173 #undef REQUIRE
174
175 typedef SkNf<2, float> Sk2f;
176 typedef SkNf<2, double> Sk2d;
177 typedef SkNf<2, SkScalar> Sk2s;
178
179 typedef SkNf<4, float> Sk4f;
180 typedef SkNf<4, double> Sk4d;
181 typedef SkNf<4, SkScalar> Sk4s;
182
183 typedef SkNi<4, int32_t> Sk4i;
12 184
13 #endif//SkNx_DEFINED 185 #endif//SkNx_DEFINED
OLDNEW
« no previous file with comments | « src/core/SkMatrix.cpp ('k') | src/core/SkPMFloat.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698