refactor setBoundsCheck() a bit
authorMike Klein <mtklein@chromium.org>
Thu, 17 May 2018 21:06:05 +0000 (17:06 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Thu, 17 May 2018 22:25:13 +0000 (22:25 +0000)
This doesn't change anything practical, but makes sure setBoundsCheck()
and setBoundsNoCheck() run through the same logic.

Bug: skia:7967

Change-Id: Ic78e2ebd5ebf46d6251c84ba93dcd397a97816fc
Reviewed-on: https://skia-review.googlesource.com/129060
Auto-Submit: Mike Klein <mtklein@chromium.org>
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Mike Reed <reed@google.com>
src/core/SkRect.cpp

index 2d6ee53f103de5a29bf9fd5de8bdd0d7af5d129d..fa7dbc0ad8bdfe8fae74d368e79848395017377d 100644 (file)
@@ -39,100 +39,49 @@ void SkRect::toQuad(SkPoint quad[4]) const {
 
 #include "SkNx.h"
 
-static inline bool is_finite(const Sk4s& value) {
-    auto finite = value * Sk4s(0) == Sk4s(0);
-    return finite.allTrue();
-}
-
 bool SkRect::setBoundsCheck(const SkPoint pts[], int count) {
     SkASSERT((pts && count > 0) || count == 0);
 
-    bool isFinite = true;
-
     if (count <= 0) {
-        sk_bzero(this, sizeof(SkRect));
+        this->setEmpty();
+        return true;
+    }
+
+    Sk4s min, max;
+    if (count & 1) {
+        min = max = Sk4s(pts->fX, pts->fY,
+                         pts->fX, pts->fY);
+        pts   += 1;
+        count -= 1;
     } else {
-        Sk4s min, max, accum;
-
-        if (count & 1) {
-            min = Sk4s(pts[0].fX, pts[0].fY, pts[0].fX, pts[0].fY);
-            pts += 1;
-            count -= 1;
-        } else {
-            min = Sk4s::Load(pts);
-            pts += 2;
-            count -= 2;
-        }
-        accum = max = min;
-        accum = accum * Sk4s(0);
-
-        count >>= 1;
-        for (int i = 0; i < count; ++i) {
-            Sk4s xy = Sk4s::Load(pts);
-            accum = accum * xy;
-            min = Sk4s::Min(min, xy);
-            max = Sk4s::Max(max, xy);
-            pts += 2;
-        }
-
-        /**
-         *  With some trickery, we may be able to use Min/Max to also propogate non-finites,
-         *  in which case we could eliminate accum entirely, and just check min and max for
-         *  "is_finite".
-         */
-        if (is_finite(accum)) {
-            float minArray[4], maxArray[4];
-            min.store(minArray);
-            max.store(maxArray);
-            this->set(SkTMin(minArray[0], minArray[2]), SkTMin(minArray[1], minArray[3]),
-                      SkTMax(maxArray[0], maxArray[2]), SkTMax(maxArray[1], maxArray[3]));
-        } else {
-            // we hit a non-finite value, so zero everything and return false
-            this->setEmpty();
-            isFinite = false;
-        }
+        min = max = Sk4s::Load(pts);
+        pts   += 2;
+        count -= 2;
     }
-    return isFinite;
-}
 
-void SkRect::setBoundsNoCheck(const SkPoint pts[], int count) {
-    SkASSERT((pts && count > 0) || count == 0);
+    Sk4s accum = min * 0;
+    while (count) {
+        Sk4s xy = Sk4s::Load(pts);
+        accum = accum * xy;
+        min = Sk4s::Min(min, xy);
+        max = Sk4s::Max(max, xy);
+        pts   += 2;
+        count -= 2;
+    }
 
-    if (count <= 0) {
-        sk_bzero(this, sizeof(SkRect));
+    bool all_finite = (accum * 0 == 0).allTrue();
+    if (all_finite) {
+        this->set(SkTMin(min[0], min[2]), SkTMin(min[1], min[3]),
+                  SkTMax(max[0], max[2]), SkTMax(max[1], max[3]));
     } else {
-        Sk4s min, max, accum;
-
-        if (count & 1) {
-            min = Sk4s(pts[0].fX, pts[0].fY, pts[0].fX, pts[0].fY);
-            pts += 1;
-            count -= 1;
-        } else {
-            min = Sk4s::Load(pts);
-            pts += 2;
-            count -= 2;
-        }
-        accum = max = min;
-        accum = accum * Sk4s(0);
-
-        count >>= 1;
-        for (int i = 0; i < count; ++i) {
-            Sk4s xy = Sk4s::Load(pts);
-            accum = accum * xy;
-            min = Sk4s::Min(min, xy);
-            max = Sk4s::Max(max, xy);
-            pts += 2;
-        }
-
-        float minArray[4], maxArray[4];
-        min.store(minArray);
-        max.store(maxArray);
-        this->set(SkTMin(minArray[0], minArray[2]), SkTMin(minArray[1], minArray[3]),
-                  SkTMax(maxArray[0], maxArray[2]), SkTMax(maxArray[1], maxArray[3]));
-
-        if (!is_finite(accum)) {
-            this->set(SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN);
-        }
+        this->setEmpty();
+    }
+    return all_finite;
+}
+
+void SkRect::setBoundsNoCheck(const SkPoint pts[], int count) {
+    if (!this->setBoundsCheck(pts, count)) {
+        this->set(SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN);
     }
 }