aboutsummaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2018-05-14 13:37:16 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-14 18:20:29 +0000
commit9236b02264d4b15208be3b8b8919f4ed441a3c85 (patch)
treef22a1d3856bca63ffb7f204ece2ecbf2c77d6f3f /include
parent9030b94c6012c7f02ba91ed352503a44c22764eb (diff)
Revert "Revert "implement SkScalar versions in terms of float versions""
This reverts commit 0e6db75eebab430e7f6665c8cfa1e7dcd2fef123. Bug: skia: Change-Id: I015d01efc58dfe03dae6bcc57c4b1102276e7566 Reviewed-on: https://skia-review.googlesource.com/127967 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Mike Reed <reed@google.com>
Diffstat (limited to 'include')
-rw-r--r--include/core/SkScalar.h20
-rw-r--r--include/private/SkFloatBits.h12
-rw-r--r--include/private/SkFloatingPoint.h30
3 files changed, 35 insertions, 27 deletions
diff --git a/include/core/SkScalar.h b/include/core/SkScalar.h
index 9c015e5ea4..938f698e05 100644
--- a/include/core/SkScalar.h
+++ b/include/core/SkScalar.h
@@ -60,7 +60,7 @@ typedef float SkScalar;
#define SkScalarToFloat(x) static_cast<float>(x)
#define SkFloatToScalar(x) static_cast<SkScalar>(x)
#define SkScalarToDouble(x) static_cast<double>(x)
-#define SkDoubleToScalar(x) static_cast<SkScalar>(x)
+#define SkDoubleToScalar(x) sk_double_to_float(x)
#define SK_ScalarMin (-SK_ScalarMax)
@@ -68,22 +68,10 @@ static inline bool SkScalarIsNaN(SkScalar x) { return x != x; }
/** Returns true if x is not NaN and not infinite
*/
-static inline bool SkScalarIsFinite(SkScalar x) {
- // We rely on the following behavior of infinities and nans
- // 0 * finite --> 0
- // 0 * infinity --> NaN
- // 0 * NaN --> NaN
- SkScalar prod = x * 0;
- // At this point, prod will either be NaN or 0
- return !SkScalarIsNaN(prod);
-}
+static inline bool SkScalarIsFinite(SkScalar x) { return sk_float_isfinite(x); }
static inline bool SkScalarsAreFinite(SkScalar a, SkScalar b) {
- SkScalar prod = 0;
- prod *= a;
- prod *= b;
- // At this point, prod will either be NaN or 0
- return !SkScalarIsNaN(prod);
+ return sk_float_isfinite(a) && sk_float_isfinite(b);
}
static inline bool SkScalarsAreFinite(const SkScalar array[], int count) {
@@ -92,7 +80,7 @@ static inline bool SkScalarsAreFinite(const SkScalar array[], int count) {
prod *= array[i];
}
// At this point, prod will either be NaN or 0
- return !SkScalarIsNaN(prod);
+ return prod == 0; // if prod is NaN, this check will return false
}
/**
diff --git a/include/private/SkFloatBits.h b/include/private/SkFloatBits.h
index 2740a25d04..bae1542a31 100644
--- a/include/private/SkFloatBits.h
+++ b/include/private/SkFloatBits.h
@@ -56,6 +56,18 @@ static inline float SkBits2Float(int32_t floatAsBits) {
return data.fFloat;
}
+constexpr int32_t gFloatBits_exponent_mask = 0x7F800000;
+constexpr int32_t gFloatBits_matissa_mask = 0x007FFFFF;
+
+static inline bool SkFloatBits_IsFinite(int32_t bits) {
+ return (bits & gFloatBits_exponent_mask) != gFloatBits_exponent_mask;
+}
+
+static inline bool SkFloatBits_IsInf(int32_t bits) {
+ return ((bits & gFloatBits_exponent_mask) == gFloatBits_exponent_mask) &&
+ (bits & gFloatBits_matissa_mask) == 0;
+}
+
/** Return the float as a 2s compliment int. Just to be used to compare floats
to each other or against positive float-bit-constants (like 0). This does
not return the int equivalent of the float, just something cheaper for
diff --git a/include/private/SkFloatingPoint.h b/include/private/SkFloatingPoint.h
index a2e6ee5122..adf7b279b9 100644
--- a/include/private/SkFloatingPoint.h
+++ b/include/private/SkFloatingPoint.h
@@ -12,6 +12,7 @@
#include "SkTypes.h"
#include "SkSafe_math.h"
#include <float.h>
+#include <math.h>
#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1
#include <xmmintrin.h>
@@ -64,17 +65,17 @@ static inline float sk_float_pow(float base, float exp) {
#define sk_float_log2(x) log2f(x)
#endif
-#ifdef SK_BUILD_FOR_WIN
- #define sk_float_isfinite(x) _finite(x)
- #define sk_float_isnan(x) _isnan(x)
- static inline int sk_float_isinf(float x) {
- return x && (x + x == x);
- }
-#else
- #define sk_float_isfinite(x) isfinite(x)
- #define sk_float_isnan(x) isnan(x)
- #define sk_float_isinf(x) isinf(x)
-#endif
+static inline bool sk_float_isfinite(float x) {
+ return SkFloatBits_IsFinite(SkFloat2Bits(x));
+}
+
+static inline bool sk_float_isinf(float x) {
+ return SkFloatBits_IsInf(SkFloat2Bits(x));
+}
+
+static inline bool sk_float_isnan(float x) {
+ return !(x == x);
+}
#define sk_double_isnan(a) sk_float_isnan(a)
@@ -200,4 +201,11 @@ static inline float sk_ieee_float_divide(float numer, float denom) {
return numer / denom;
}
+#ifdef __clang__
+__attribute__((no_sanitize("float-divide-by-zero")))
+#endif
+static inline double sk_ieee_double_divide(double numer, double denom) {
+ return numer / denom;
+}
+
#endif