diff options
author | Mike Reed <reed@google.com> | 2018-05-14 13:37:16 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-05-14 18:20:29 +0000 |
commit | 9236b02264d4b15208be3b8b8919f4ed441a3c85 (patch) | |
tree | f22a1d3856bca63ffb7f204ece2ecbf2c77d6f3f /include | |
parent | 9030b94c6012c7f02ba91ed352503a44c22764eb (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.h | 20 | ||||
-rw-r--r-- | include/private/SkFloatBits.h | 12 | ||||
-rw-r--r-- | include/private/SkFloatingPoint.h | 30 |
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 |