aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2018-01-31 15:55:47 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-01-31 21:21:36 +0000
commit3d5a6b5f25b0e1c0bf23106f55e736b1bf0d9be8 (patch)
treed37b0571949244fd17cca56c9633e0b208444136
parent17823764300ff33ce5969113a818eb8de7cef3fc (diff)
add saturate helper for float2int64
Bug: skia: Change-Id: I157f8c047145874c4585ae870018163908389b26 Reviewed-on: https://skia-review.googlesource.com/102321 Reviewed-by: Mike Klein <mtklein@google.com> Reviewed-by: Florin Malita <fmalita@chromium.org>
-rw-r--r--include/core/SkTypes.h2
-rw-r--r--include/private/SkFixed.h4
-rw-r--r--include/private/SkFloatingPoint.h12
-rw-r--r--tests/MathTest.cpp26
4 files changed, 40 insertions, 4 deletions
diff --git a/include/core/SkTypes.h b/include/core/SkTypes.h
index 50efbaea0e..afab728666 100644
--- a/include/core/SkTypes.h
+++ b/include/core/SkTypes.h
@@ -212,6 +212,8 @@ template <typename D, typename S> constexpr D SkTo(S s) {
#define SK_MinU32 0
#define SK_NaN32 ((int) (1U << 31))
#define SK_MaxSizeT SIZE_MAX
+static constexpr int64_t SK_MaxS64 = 0x7FFFFFFFFFFFFFFF;
+static constexpr int64_t SK_MinS64 = -SK_MaxS64;
static inline int32_t SkLeftShift(int32_t value, int32_t shift) {
return (int32_t) ((uint32_t) value << shift);
diff --git a/include/private/SkFixed.h b/include/private/SkFixed.h
index 05e1de49c9..75514d8f1e 100644
--- a/include/private/SkFixed.h
+++ b/include/private/SkFixed.h
@@ -124,14 +124,14 @@ static inline SkFixed SkFixedMul(SkFixed a, SkFixed b) {
typedef int64_t SkFixed3232; // 32.32
-#define SkFixed3232Max (0x7FFFFFFFFFFFFFFFLL)
+#define SkFixed3232Max SK_MaxS64
#define SkFixed3232Min (-SkFixed3232Max)
#define SkIntToFixed3232(x) (SkLeftShift((SkFixed3232)(x), 32))
#define SkFixed3232ToInt(x) ((int)((x) >> 32))
#define SkFixedToFixed3232(x) (SkLeftShift((SkFixed3232)(x), 16))
#define SkFixed3232ToFixed(x) ((SkFixed)((x) >> 16))
-#define SkFloatToFixed3232(x) ((SkFixed3232)((x) * (65536.0f * 65536.0f)))
+#define SkFloatToFixed3232(x) sk_float_saturate2int64((x) * (65536.0f * 65536.0f))
#define SkFixed3232ToFloat(x) (x * (1 / (65536.0f * 65536.0f)))
#define SkScalarToFixed3232(x) SkFloatToFixed3232(x)
diff --git a/include/private/SkFloatingPoint.h b/include/private/SkFloatingPoint.h
index 05191e651d..bbb117982f 100644
--- a/include/private/SkFloatingPoint.h
+++ b/include/private/SkFloatingPoint.h
@@ -81,6 +81,9 @@ static inline float sk_float_pow(float base, float exp) {
#define SK_MaxS32FitsInFloat 2147483520
#define SK_MinS32FitsInFloat -SK_MaxS32FitsInFloat
+#define SK_MaxS64FitsInFloat (SK_MaxS64 >> (63-24) << (63-24)) // 0x7fffff8000000000
+#define SK_MinS64FitsInFloat -SK_MaxS64FitsInFloat
+
/**
* Return the closest int for the given float. Returns SK_MaxS32FitsInFloat for NaN.
*/
@@ -99,6 +102,15 @@ static inline int sk_double_saturate2int(double x) {
return (int)x;
}
+/**
+ * Return the closest int64_t for the given float. Returns SK_MaxS64FitsInFloat for NaN.
+ */
+static inline int64_t sk_float_saturate2int64(float x) {
+ x = SkTMin<float>(x, SK_MaxS64FitsInFloat);
+ x = SkTMax<float>(x, SK_MinS64FitsInFloat);
+ return (int64_t)x;
+}
+
#define sk_float_floor2int(x) sk_float_saturate2int(sk_float_floor(x))
#define sk_float_round2int(x) sk_float_saturate2int(sk_float_floor((x) + 0.5f))
#define sk_float_ceil2int(x) sk_float_saturate2int(sk_float_ceil(x))
diff --git a/tests/MathTest.cpp b/tests/MathTest.cpp
index 0d0bdce67d..31bb45308c 100644
--- a/tests/MathTest.cpp
+++ b/tests/MathTest.cpp
@@ -672,7 +672,7 @@ DEF_TEST(GrNextSizePow2, reporter) {
test_nextsizepow2(reporter, SIZE_MAX, SIZE_MAX);
}
-DEF_TEST(FloatSaturate, reporter) {
+DEF_TEST(FloatSaturate32, reporter) {
const struct {
float fFloat;
int fExpectedInt;
@@ -694,7 +694,29 @@ DEF_TEST(FloatSaturate, reporter) {
}
}
-DEF_TEST(DoubleSaturate, reporter) {
+DEF_TEST(FloatSaturate64, reporter) {
+ const struct {
+ float fFloat;
+ int64_t fExpected64;
+ } recs[] = {
+ { 0, 0 },
+ { 100.5f, 100 },
+ { (float)SK_MaxS64, SK_MaxS64FitsInFloat },
+ { (float)SK_MinS64, SK_MinS64FitsInFloat },
+ { SK_MaxS64 * 100.0f, SK_MaxS64FitsInFloat },
+ { SK_MinS64 * 100.0f, SK_MinS64FitsInFloat },
+ { SK_ScalarInfinity, SK_MaxS64FitsInFloat },
+ { SK_ScalarNegativeInfinity, SK_MinS64FitsInFloat },
+ { SK_ScalarNaN, SK_MaxS64FitsInFloat },
+ };
+
+ for (auto r : recs) {
+ int64_t i = sk_float_saturate2int64(r.fFloat);
+ REPORTER_ASSERT(reporter, r.fExpected64 == i);
+ }
+}
+
+DEF_TEST(DoubleSaturate32, reporter) {
const struct {
double fDouble;
int fExpectedInt;