Replace raster pipeline nextafter() calls with SkNu nudging
authorFlorin Malita <fmalita@chromium.org>
Fri, 20 Jan 2017 19:53:03 +0000 (14:53 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Fri, 20 Jan 2017 20:25:57 +0000 (20:25 +0000)
(courtesy of mtklein@)

  nanobench -m gradient_linear_clamp\$ --config f16 --ms 2000 -q

Before: 753.66
After:  658.69

R=mtklein@google.com,herb@google.com

CQ_INCLUDE_TRYBOTS=skia.primary:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD

Change-Id: Ie1442da340f6cfc9aef65bec1f114c0e5db89fcb
Reviewed-on: https://skia-review.googlesource.com/7351
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>

src/opts/SkRasterPipeline_opts.h

index aa66d73..5491535 100644 (file)
@@ -871,21 +871,28 @@ SI SkNf assert_in_tile(const SkNf& v, float limit) {
     return v;
 }
 
+SI SkNf ulp_before(float v) {
+    SkASSERT(v > 0);
+    SkNf vs(v);
+    SkNu uvs = SkNu::Load(&vs) - 1;
+    return SkNf::Load(&uvs);
+}
+
 SI SkNf clamp(const SkNf& v, float limit) {
-    SkNf result = SkNf::Max(0, SkNf::Min(v, nextafterf(limit, 0)));
+    SkNf result = SkNf::Max(0, SkNf::Min(v, ulp_before(limit)));
     return assert_in_tile(result, limit);
 }
 SI SkNf repeat(const SkNf& v, float limit) {
     SkNf result = v - (v/limit).floor()*limit;
     // For small negative v, (v/limit).floor()*limit can dominate v in the subtraction,
     // which leaves result == limit.  We want result < limit, so clamp it one ULP.
-    result = SkNf::Min(result, nextafterf(limit, 0));
+    result = SkNf::Min(result, ulp_before(limit));
     return assert_in_tile(result, limit);
 }
 SI SkNf mirror(const SkNf& v, float l/*imit*/) {
     SkNf result = ((v - l) - ((v - l) / (2*l)).floor()*(2*l) - l).abs();
     // Same deal as repeat.
-    result = SkNf::Min(result, nextafterf(l, 0));
+    result = SkNf::Min(result, ulp_before(l));
     return assert_in_tile(result, l);
 }
 STAGE_CTX( clamp_x, const float*) { r = clamp (r, *ctx); }