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

Side by Side Diff: include/core/SkFloatingPoint.h

Issue 1251423002: Update fallback rsqrt implementation to use optimal constants. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 5 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 | « no previous file | tests/MathTest.cpp » ('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 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 9
10 #ifndef SkFloatingPoint_DEFINED 10 #ifndef SkFloatingPoint_DEFINED
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 #define SK_FloatNegativeInfinity (*SkTCast<const float*>(&gIEEENegativeInfini ty)) 144 #define SK_FloatNegativeInfinity (*SkTCast<const float*>(&gIEEENegativeInfini ty))
145 145
146 // Fast, approximate inverse square root. 146 // Fast, approximate inverse square root.
147 // Compare to name-brand "1.0f / sk_float_sqrt(x)". Should be around 10x faster on SSE, 2x on NEON. 147 // Compare to name-brand "1.0f / sk_float_sqrt(x)". Should be around 10x faster on SSE, 2x on NEON.
148 static inline float sk_float_rsqrt(const float x) { 148 static inline float sk_float_rsqrt(const float x) {
149 // We want all this inlined, so we'll inline SIMD and just take the hit when we don't know we've got 149 // We want all this inlined, so we'll inline SIMD and just take the hit when we don't know we've got
150 // it at compile time. This is going to be too fast to productively hide behind a function pointer. 150 // it at compile time. This is going to be too fast to productively hide behind a function pointer.
151 // 151 //
152 // We do one step of Newton's method to refine the estimates in the NEON and nul l paths. No 152 // We do one step of Newton's method to refine the estimates in the NEON and nul l paths. No
153 // refinement is faster, but very innacurate. Two steps is more accurate, but s lower than 1/sqrt. 153 // refinement is faster, but very innacurate. Two steps is more accurate, but s lower than 1/sqrt.
154 //
155 // Optimized constants in the null path courtesy of http://rrrola.wz.cz/inv_sqrt .html
154 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1 156 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1
155 return _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(x))); 157 return _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(x)));
156 #elif defined(SK_ARM_HAS_NEON) 158 #elif defined(SK_ARM_HAS_NEON)
157 // Get initial estimate. 159 // Get initial estimate.
158 const float32x2_t xx = vdup_n_f32(x); // Clever readers will note we're doi ng everything 2x. 160 const float32x2_t xx = vdup_n_f32(x); // Clever readers will note we're doi ng everything 2x.
159 float32x2_t estimate = vrsqrte_f32(xx); 161 float32x2_t estimate = vrsqrte_f32(xx);
160 162
161 // One step of Newton's method to refine. 163 // One step of Newton's method to refine.
162 const float32x2_t estimate_sq = vmul_f32(estimate, estimate); 164 const float32x2_t estimate_sq = vmul_f32(estimate, estimate);
163 estimate = vmul_f32(estimate, vrsqrts_f32(xx, estimate_sq)); 165 estimate = vmul_f32(estimate, vrsqrts_f32(xx, estimate_sq));
164 return vget_lane_f32(estimate, 0); // 1 will work fine too; the answer's in both places. 166 return vget_lane_f32(estimate, 0); // 1 will work fine too; the answer's in both places.
165 #else 167 #else
166 // Get initial estimate. 168 // Get initial estimate.
167 int i = *SkTCast<int*>(&x); 169 int i = *SkTCast<int*>(&x);
168 i = 0x5f3759df - (i>>1); 170 i = 0x5F1FFFF9 - (i>>1);
169 float estimate = *SkTCast<float*>(&i); 171 float estimate = *SkTCast<float*>(&i);
170 172
171 // One step of Newton's method to refine. 173 // One step of Newton's method to refine.
172 const float estimate_sq = estimate*estimate; 174 const float estimate_sq = estimate*estimate;
173 estimate *= (1.5f-0.5f*x*estimate_sq); 175 estimate *= 0.703952253f*(2.38924456f-x*estimate_sq);
174 return estimate; 176 return estimate;
175 #endif 177 #endif
176 } 178 }
177 179
178 #endif 180 #endif
OLDNEW
« no previous file with comments | « no previous file | tests/MathTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698