Chromium Code Reviews| Index: include/core/SkFixed.h |
| diff --git a/include/core/SkFixed.h b/include/core/SkFixed.h |
| index 8bbf2f0dfec48e298a3953843a58129601014202..09b3c33b221cf795d642fe12b8cd125b61ea136c 100644 |
| --- a/include/core/SkFixed.h |
| +++ b/include/core/SkFixed.h |
| @@ -29,8 +29,64 @@ typedef int32_t SkFixed; |
| #define SK_FixedTanPIOver8 (0x6A0A) |
| #define SK_FixedRoot2Over2 (0xB505) |
| -#define SkFixedToFloat(x) ((x) * 1.52587890625e-5f) |
| -#define SkFloatToFixed(x) ((SkFixed)((x) * SK_Fixed1)) |
| +#define SkFixedToFloat(x) ((x) * 1.52587890625e-5f) |
|
mtklein
2016/03/23 02:16:41
This may no longer need its new indentation.
|
| + |
| +/////////////////////////////////////////////////////////////////////////////// |
| +// ASM alternatives for our portable versions. |
| + |
| +#if defined(SK_CPU_ARM32) |
| + /* This guy does not handle NaN or other obscurities, but is faster than |
| + than (int)(x*65536). When built on Android with -Os, needs forcing |
| + to inline or we lose the speed benefit. |
| + */ |
| + SK_ALWAYS_INLINE SkFixed SkFloatToFixed_arm(float x) |
| + { |
| + int32_t y, z; |
| + asm("movs %1, %3, lsl #1 \n" |
| + "mov %2, #0x8E \n" |
| + "sub %1, %2, %1, lsr #24 \n" |
| + "mov %2, %3, lsl #8 \n" |
| + "orr %2, %2, #0x80000000 \n" |
| + "mov %1, %2, lsr %1 \n" |
| + "it cs \n" |
| + "rsbcs %1, %1, #0 \n" |
| + : "=r"(x), "=&r"(y), "=&r"(z) |
| + : "r"(x) |
| + : "cc" |
| + ); |
| + return y; |
| + } |
| + inline SkFixed SkFixedMul_arm(SkFixed x, SkFixed y) |
| + { |
| + int32_t t; |
| + asm("smull %0, %2, %1, %3 \n" |
| + "mov %0, %0, lsr #16 \n" |
| + "orr %0, %0, %2, lsl #16 \n" |
| + : "=r"(x), "=&r"(y), "=r"(t) |
| + : "r"(x), "1"(y) |
| + : |
| + ); |
| + return x; |
| + } |
| + |
| + #define SkFixedMul(x, y) SkFixedMul_arm(x, y) |
| + #define SkFloatToFixed_Unsafe(x) SkFloatToFixed_arm(x) |
| +#else |
| + inline SkFixed SkFixedMul_longlong(SkFixed a, SkFixed b) { |
| + return (SkFixed)((int64_t)a * b >> 16); |
| + } |
| + |
| + #define SkFixedMul(x, y) SkFixedMul_longlong(x, y) |
| + #define SkFloatToFixed_Unsafe(x) ((SkFixed)((x) * SK_Fixed1)) |
| +#endif |
| + |
| +/////////////////////////////////////////////////////////////////////////////// |
| + |
| +static inline SkFixed SkFloatToFixed(float x) { |
| + const SkFixed result = SkFloatToFixed_Unsafe(x); |
| + SkASSERT(truncf(x * SK_Fixed1) == static_cast<float>(result)); |
| + return result; |
| +} |
| // Pins over/under flows to SK_FixedMax/SK_FixedMin (slower than just a cast). |
| static inline SkFixed SkFloatPinToFixed(float x) { |
| @@ -43,19 +99,14 @@ static inline SkFixed SkFloatPinToFixed(float x) { |
| return result; |
| } |
| -#ifdef SK_DEBUG |
| - static inline SkFixed SkFloatToFixed_Check(float x) { |
| - int64_t n64 = (int64_t)(x * SK_Fixed1); |
| - SkFixed n32 = (SkFixed)n64; |
| - SkASSERT(n64 == n32); |
| - return n32; |
| - } |
| -#else |
| - #define SkFloatToFixed_Check(x) SkFloatToFixed(x) |
| -#endif |
| +#define SkFixedToDouble(x) ((x) * 1.52587890625e-5) |
| +#define SkDoubleToFixed_Unsafe(x) ((SkFixed)((x) * SK_Fixed1)) |
| -#define SkFixedToDouble(x) ((x) * 1.52587890625e-5) |
| -#define SkDoubleToFixed(x) ((SkFixed)((x) * SK_Fixed1)) |
| +static inline SkFixed SkDoubleToFixed(double x) { |
| + const SkFixed result = SkDoubleToFixed_Unsafe(x); |
| + SkASSERT(trunc(x * SK_Fixed1) == static_cast<double>(result)); |
| + return result; |
| +} |
| // Pins over/under flows to SK_FixedMax/SK_FixedMin (slower than just a cast). |
| static inline SkFixed SkDoublePinToFixed(double x) { |
| @@ -106,65 +157,22 @@ static inline SkFixed SkDoublePinToFixed(double x) { |
| SkToS32(SkTPin<int64_t>((SkLeftShift((int64_t)numer, 16) / denom), SK_MinS32, SK_MaxS32)) |
| #endif |
| -////////////////////////////////////////////////////////////////////////////////////////////////////// |
| -// Now look for ASM overrides for our portable versions (should consider putting this in its own file) |
| - |
| -inline SkFixed SkFixedMul_longlong(SkFixed a, SkFixed b) { |
| - return (SkFixed)((int64_t)a * b >> 16); |
| -} |
| -#define SkFixedMul(a,b) SkFixedMul_longlong(a,b) |
| - |
| - |
| -#if defined(SK_CPU_ARM32) |
| - /* This guy does not handle NaN or other obscurities, but is faster than |
| - than (int)(x*65536). When built on Android with -Os, needs forcing |
| - to inline or we lose the speed benefit. |
| - */ |
| - SK_ALWAYS_INLINE SkFixed SkFloatToFixed_arm(float x) |
| - { |
| - int32_t y, z; |
| - asm("movs %1, %3, lsl #1 \n" |
| - "mov %2, #0x8E \n" |
| - "sub %1, %2, %1, lsr #24 \n" |
| - "mov %2, %3, lsl #8 \n" |
| - "orr %2, %2, #0x80000000 \n" |
| - "mov %1, %2, lsr %1 \n" |
| - "it cs \n" |
| - "rsbcs %1, %1, #0 \n" |
| - : "=r"(x), "=&r"(y), "=&r"(z) |
| - : "r"(x) |
| - : "cc" |
| - ); |
| - return y; |
| - } |
| - inline SkFixed SkFixedMul_arm(SkFixed x, SkFixed y) |
| - { |
| - int32_t t; |
| - asm("smull %0, %2, %1, %3 \n" |
| - "mov %0, %0, lsr #16 \n" |
| - "orr %0, %0, %2, lsl #16 \n" |
| - : "=r"(x), "=&r"(y), "=r"(t) |
| - : "r"(x), "1"(y) |
| - : |
| - ); |
| - return x; |
| - } |
| - #undef SkFixedMul |
| - #define SkFixedMul(x, y) SkFixedMul_arm(x, y) |
| - |
| - #undef SkFloatToFixed |
| - #define SkFloatToFixed(x) SkFloatToFixed_arm(x) |
| -#endif |
| - |
| /////////////////////////////////////////////////////////////////////////////// |
| typedef int64_t SkFixed3232; // 32.32 |
| -#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 SK_Fixed3232_1 (static_cast<SkFixed3232>(1) << 32) |
| +#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_Unsafe(x) (static_cast<SkFixed3232>((x) * SK_Fixed3232_1)) |
| + |
| +static inline SkFixed3232 SkFloatToFixed3232(float x) { |
| + const SkFixed3232 result = SkFloatToFixed3232_Unsafe(x); |
| + SkASSERT(truncf(x * SK_Fixed3232_1) == static_cast<float>(result)); |
| + return result; |
| +} |
| #define SkScalarToFixed3232(x) SkFloatToFixed3232(x) |