aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@chromium.org>2018-05-17 17:06:05 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-17 22:25:13 +0000
commitc38576708543ded1609fdd7b70fee639e60591ea (patch)
tree771bc85775b3d469def36e2b48f21e8680162b9d
parent25cb7c81746030d9286043054b1563cd5f32c32d (diff)
refactor setBoundsCheck() a bit
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>
-rw-r--r--src/core/SkRect.cpp119
1 files changed, 34 insertions, 85 deletions
diff --git a/src/core/SkRect.cpp b/src/core/SkRect.cpp
index 2d6ee53f10..fa7dbc0ad8 100644
--- a/src/core/SkRect.cpp
+++ b/src/core/SkRect.cpp
@@ -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);
}
}