Add pinned versions of *ToFixed.
BUG=skia:4632 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1707023002 Review URL: https://codereview.chromium.org/1707023002
This commit is contained in:
parent
73add93a9c
commit
70f1a6c64e
@ -9,6 +9,8 @@
|
||||
#define SkFixed_DEFINED
|
||||
|
||||
#include "SkScalar.h"
|
||||
#include "math.h"
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/** \file SkFixed.h
|
||||
@ -29,15 +31,18 @@ typedef int32_t SkFixed;
|
||||
#define SK_FixedRoot2Over2 (0xB505)
|
||||
|
||||
#define SkFixedToFloat(x) ((x) * 1.52587890625e-5f)
|
||||
#if 1
|
||||
#define SkFloatToFixed(x) ((SkFixed)((x) * SK_Fixed1))
|
||||
#else
|
||||
// pins over/under flows to max/min int32 (slower than just a cast)
|
||||
static inline SkFixed SkFloatToFixed(float x) {
|
||||
int64_t n = x * SK_Fixed1;
|
||||
return (SkFixed)n;
|
||||
}
|
||||
#endif
|
||||
#define SkFloatToFixed(x) ((SkFixed)((x) * SK_Fixed1))
|
||||
|
||||
// Pins over/under flows to SK_FixedMax/SK_FixedMin (slower than just a cast).
|
||||
static inline SkFixed SkFloatPinToFixed(float x) {
|
||||
x *= SK_Fixed1;
|
||||
// Casting float to int outside the range of the target type (int32_t) is undefined behavior.
|
||||
if (x >= SK_FixedMax) return SK_FixedMax;
|
||||
if (x <= SK_FixedMin) return SK_FixedMin;
|
||||
const SkFixed result = static_cast<SkFixed>(x);
|
||||
SkASSERT(truncf(x) == static_cast<float>(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
static inline SkFixed SkFloatToFixed_Check(float x) {
|
||||
@ -53,6 +58,17 @@ typedef int32_t SkFixed;
|
||||
#define SkFixedToDouble(x) ((x) * 1.52587890625e-5)
|
||||
#define SkDoubleToFixed(x) ((SkFixed)((x) * SK_Fixed1))
|
||||
|
||||
// Pins over/under flows to SK_FixedMax/SK_FixedMin (slower than just a cast).
|
||||
static inline SkFixed SkDoublePinToFixed(double x) {
|
||||
x *= SK_Fixed1;
|
||||
// Casting double to int outside the range of the target type (int32_t) is undefined behavior.
|
||||
if (x >= SK_FixedMax) return SK_FixedMax;
|
||||
if (x <= SK_FixedMin) return SK_FixedMin;
|
||||
const SkFixed result = static_cast<SkFixed>(x);
|
||||
SkASSERT(trunc(x) == static_cast<double>(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Converts an integer to a SkFixed, asserting that the result does not overflow
|
||||
a 32 bit signed integer
|
||||
*/
|
||||
@ -147,11 +163,13 @@ inline SkFixed SkFixedMul_longlong(SkFixed a, SkFixed b) {
|
||||
|
||||
#define SkFixedToScalar(x) SkFixedToFloat(x)
|
||||
#define SkScalarToFixed(x) SkFloatToFixed(x)
|
||||
#define SkScalarPinToFixed(x) SkFloatPinToFixed(x)
|
||||
|
||||
#else // SK_SCALAR_IS_DOUBLE
|
||||
|
||||
#define SkFixedToScalar(x) SkFixedToDouble(x)
|
||||
#define SkScalarToFixed(x) SkDoubleToFixed(x)
|
||||
#define SkScalarPinToFixed(x) SkDoublePinToFixed(x)
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "float.h"
|
||||
|
||||
#include "SkColorPriv.h"
|
||||
#include "SkEndian.h"
|
||||
#include "SkFixed.h"
|
||||
@ -697,3 +699,41 @@ DEF_TEST(divmod_s32, r) {
|
||||
DEF_TEST(divmod_s64, r) {
|
||||
test_divmod<int64_t>(r);
|
||||
}
|
||||
|
||||
DEF_TEST(PinToFixed, reporter) {
|
||||
// double
|
||||
REPORTER_ASSERT(reporter, 0 == SkDoublePinToFixed(0.0));
|
||||
REPORTER_ASSERT(reporter, 0x10000 == SkDoublePinToFixed(1.0));
|
||||
REPORTER_ASSERT(reporter, 0x7FFFFFFE == SkDoublePinToFixed(32767.999984741));
|
||||
REPORTER_ASSERT(reporter, 0x7FFFFFFF == SkDoublePinToFixed(32767.999984742));
|
||||
REPORTER_ASSERT(reporter, 0x7FFFFFFF == SkDoublePinToFixed(32767.999999999));
|
||||
REPORTER_ASSERT(reporter, 0x7FFFFFFF == SkDoublePinToFixed(32768.0));
|
||||
REPORTER_ASSERT(reporter, 0x7FFFFFFF == SkDoublePinToFixed(5e10));
|
||||
REPORTER_ASSERT(reporter, 0x7FFFFFFF == SkDoublePinToFixed(DBL_MAX));
|
||||
REPORTER_ASSERT(reporter, -0x10000 == SkDoublePinToFixed(-1.0));
|
||||
// SK_FixedMin is defined to be -SK_FixedMax.
|
||||
REPORTER_ASSERT(reporter, -0x7FFFFFFE == SkDoublePinToFixed(-32767.999984741));
|
||||
REPORTER_ASSERT(reporter, -0x7FFFFFFF == SkDoublePinToFixed(-32767.999984742));
|
||||
REPORTER_ASSERT(reporter, -0x7FFFFFFF == SkDoublePinToFixed(-32767.999999999));
|
||||
REPORTER_ASSERT(reporter, -0x7FFFFFFF == SkDoublePinToFixed(-32768.0));
|
||||
REPORTER_ASSERT(reporter, -0x7FFFFFFF == SkDoublePinToFixed(-5e10));
|
||||
REPORTER_ASSERT(reporter, -0x7FFFFFFF == SkDoublePinToFixed(-DBL_MAX));
|
||||
|
||||
// float
|
||||
REPORTER_ASSERT(reporter, 0 == SkFloatPinToFixed(0.0f));
|
||||
REPORTER_ASSERT(reporter, 0x10000 == SkFloatPinToFixed(1.0f));
|
||||
// SkFixed has more precision than float near SK_FixedMax, so SkFloatPinToFixed will never
|
||||
// produce output between 0x7FFFFF80 and 0x7FFFFFFF.
|
||||
REPORTER_ASSERT(reporter, 0x7FFFFF80 == SkFloatPinToFixed(32767.9990f));
|
||||
REPORTER_ASSERT(reporter, 0x7FFFFFFF == SkFloatPinToFixed(32767.9991f));
|
||||
REPORTER_ASSERT(reporter, 0x7FFFFFFF == SkFloatPinToFixed(32768.0f));
|
||||
REPORTER_ASSERT(reporter, 0x7FFFFFFF == SkFloatPinToFixed(5e10f));
|
||||
REPORTER_ASSERT(reporter, 0x7FFFFFFF == SkFloatPinToFixed(FLT_MAX));
|
||||
REPORTER_ASSERT(reporter, -0x10000 == SkFloatPinToFixed(-1.0f));
|
||||
// SK_FixedMin is defined to be -SK_FixedMax.
|
||||
REPORTER_ASSERT(reporter, -0x7FFFFF80 == SkFloatPinToFixed(-32767.9990f));
|
||||
REPORTER_ASSERT(reporter, -0x7FFFFFFF == SkFloatPinToFixed(-32767.9991f));
|
||||
REPORTER_ASSERT(reporter, -0x7FFFFFFF == SkFloatPinToFixed(-32768.0f));
|
||||
REPORTER_ASSERT(reporter, -0x7FFFFFFF == SkFloatPinToFixed(-5e10f));
|
||||
REPORTER_ASSERT(reporter, -0x7FFFFFFF == SkFloatPinToFixed(-FLT_MAX));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user