| 1 | /* | 
|---|
| 2 | * Copyright 2006 The Android Open Source Project | 
|---|
| 3 | * | 
|---|
| 4 | * Use of this source code is governed by a BSD-style license that can be | 
|---|
| 5 | * found in the LICENSE file. | 
|---|
| 6 | */ | 
|---|
| 7 |  | 
|---|
| 8 | #ifndef SkFixed_DEFINED | 
|---|
| 9 | #define SkFixed_DEFINED | 
|---|
| 10 |  | 
|---|
| 11 | #include "include/core/SkScalar.h" | 
|---|
| 12 | #include "include/core/SkTypes.h" | 
|---|
| 13 | #include "include/private/SkSafe_math.h" | 
|---|
| 14 | #include "include/private/SkTo.h" | 
|---|
| 15 |  | 
|---|
| 16 | /** \file SkFixed.h | 
|---|
| 17 |  | 
|---|
| 18 | Types and macros for 16.16 fixed point | 
|---|
| 19 | */ | 
|---|
| 20 |  | 
|---|
| 21 | /** 32 bit signed integer used to represent fractions values with 16 bits to the right of the decimal point | 
|---|
| 22 | */ | 
|---|
| 23 | typedef int32_t             SkFixed; | 
|---|
| 24 | #define SK_Fixed1           (1 << 16) | 
|---|
| 25 | #define SK_FixedHalf        (1 << 15) | 
|---|
| 26 | #define SK_FixedQuarter     (1 << 14) | 
|---|
| 27 | #define SK_FixedMax         (0x7FFFFFFF) | 
|---|
| 28 | #define SK_FixedMin         (-SK_FixedMax) | 
|---|
| 29 | #define SK_FixedPI          (0x3243F) | 
|---|
| 30 | #define SK_FixedSqrt2       (92682) | 
|---|
| 31 | #define SK_FixedTanPIOver8  (0x6A0A) | 
|---|
| 32 | #define SK_FixedRoot2Over2  (0xB505) | 
|---|
| 33 |  | 
|---|
| 34 | // NOTE: SkFixedToFloat is exact. SkFloatToFixed seems to lack a rounding step. For all fixed-point | 
|---|
| 35 | // values, this version is as accurate as possible for (fixed -> float -> fixed). Rounding reduces | 
|---|
| 36 | // accuracy if the intermediate floats are in the range that only holds integers (adding 0.5f to an | 
|---|
| 37 | // odd integer then snaps to nearest even). Using double for the rounding math gives maximum | 
|---|
| 38 | // accuracy for (float -> fixed -> float), but that's usually overkill. | 
|---|
| 39 | #define SkFixedToFloat(x)   ((x) * 1.52587890625e-5f) | 
|---|
| 40 | #define SkFloatToFixed(x)   sk_float_saturate2int((x) * SK_Fixed1) | 
|---|
| 41 |  | 
|---|
| 42 | #ifdef SK_DEBUG | 
|---|
| 43 | static inline SkFixed SkFloatToFixed_Check(float x) { | 
|---|
| 44 | int64_t n64 = (int64_t)(x * SK_Fixed1); | 
|---|
| 45 | SkFixed n32 = (SkFixed)n64; | 
|---|
| 46 | SkASSERT(n64 == n32); | 
|---|
| 47 | return n32; | 
|---|
| 48 | } | 
|---|
| 49 | #else | 
|---|
| 50 | #define SkFloatToFixed_Check(x) SkFloatToFixed(x) | 
|---|
| 51 | #endif | 
|---|
| 52 |  | 
|---|
| 53 | #define SkFixedToDouble(x)  ((x) * 1.52587890625e-5) | 
|---|
| 54 | #define SkDoubleToFixed(x)  ((SkFixed)((x) * SK_Fixed1)) | 
|---|
| 55 |  | 
|---|
| 56 | /** Converts an integer to a SkFixed, asserting that the result does not overflow | 
|---|
| 57 | a 32 bit signed integer | 
|---|
| 58 | */ | 
|---|
| 59 | #ifdef SK_DEBUG | 
|---|
| 60 | inline SkFixed SkIntToFixed(int n) | 
|---|
| 61 | { | 
|---|
| 62 | SkASSERT(n >= -32768 && n <= 32767); | 
|---|
| 63 | // Left shifting a negative value has undefined behavior in C, so we cast to unsigned before | 
|---|
| 64 | // shifting. | 
|---|
| 65 | return (SkFixed)( (unsigned)n << 16 ); | 
|---|
| 66 | } | 
|---|
| 67 | #else | 
|---|
| 68 | // Left shifting a negative value has undefined behavior in C, so we cast to unsigned before | 
|---|
| 69 | // shifting. Then we force the cast to SkFixed to ensure that the answer is signed (like the | 
|---|
| 70 | // debug version). | 
|---|
| 71 | #define SkIntToFixed(n)     (SkFixed)((unsigned)(n) << 16) | 
|---|
| 72 | #endif | 
|---|
| 73 |  | 
|---|
| 74 | #define SkFixedRoundToInt(x)    (((x) + SK_FixedHalf) >> 16) | 
|---|
| 75 | #define SkFixedCeilToInt(x)     (((x) + SK_Fixed1 - 1) >> 16) | 
|---|
| 76 | #define SkFixedFloorToInt(x)    ((x) >> 16) | 
|---|
| 77 |  | 
|---|
| 78 | static inline SkFixed SkFixedRoundToFixed(SkFixed x) { | 
|---|
| 79 | return (SkFixed)( (uint32_t)(x + SK_FixedHalf) & 0xFFFF0000 ); | 
|---|
| 80 | } | 
|---|
| 81 | static inline SkFixed SkFixedCeilToFixed(SkFixed x) { | 
|---|
| 82 | return (SkFixed)( (uint32_t)(x + SK_Fixed1 - 1) & 0xFFFF0000 ); | 
|---|
| 83 | } | 
|---|
| 84 | static inline SkFixed SkFixedFloorToFixed(SkFixed x) { | 
|---|
| 85 | return (SkFixed)( (uint32_t)x & 0xFFFF0000 ); | 
|---|
| 86 | } | 
|---|
| 87 |  | 
|---|
| 88 | #define SkFixedAbs(x)       SkAbs32(x) | 
|---|
| 89 | #define SkFixedAve(a, b)    (((a) + (b)) >> 1) | 
|---|
| 90 |  | 
|---|
| 91 | // The divide may exceed 32 bits. Clamp to a signed 32 bit result. | 
|---|
| 92 | #define SkFixedDiv(numer, denom) \ | 
|---|
| 93 | SkToS32(SkTPin<int64_t>((SkLeftShift((int64_t)(numer), 16) / (denom)), SK_MinS32, SK_MaxS32)) | 
|---|
| 94 |  | 
|---|
| 95 | static inline SkFixed SkFixedMul(SkFixed a, SkFixed b) { | 
|---|
| 96 | return (SkFixed)((int64_t)a * b >> 16); | 
|---|
| 97 | } | 
|---|
| 98 |  | 
|---|
| 99 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 100 | // Platform-specific alternatives to our portable versions. | 
|---|
| 101 |  | 
|---|
| 102 | // The VCVT float-to-fixed instruction is part of the VFPv3 instruction set. | 
|---|
| 103 | #if defined(__ARM_VFPV3__) | 
|---|
| 104 | /* This does not handle NaN or other obscurities, but is faster than | 
|---|
| 105 | than (int)(x*65536).  When built on Android with -Os, needs forcing | 
|---|
| 106 | to inline or we lose the speed benefit. | 
|---|
| 107 | */ | 
|---|
| 108 | SK_ALWAYS_INLINE SkFixed SkFloatToFixed_arm(float x) | 
|---|
| 109 | { | 
|---|
| 110 | int32_t y; | 
|---|
| 111 | asm( "vcvt.s32.f32 %0, %0, #16": "+w"(x)); | 
|---|
| 112 | memcpy(&y, &x, sizeof(y)); | 
|---|
| 113 | return y; | 
|---|
| 114 | } | 
|---|
| 115 | #undef SkFloatToFixed | 
|---|
| 116 | #define SkFloatToFixed(x)  SkFloatToFixed_arm(x) | 
|---|
| 117 | #endif | 
|---|
| 118 |  | 
|---|
| 119 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 120 |  | 
|---|
| 121 | #define SkFixedToScalar(x)          SkFixedToFloat(x) | 
|---|
| 122 | #define SkScalarToFixed(x)          SkFloatToFixed(x) | 
|---|
| 123 |  | 
|---|
| 124 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 125 |  | 
|---|
| 126 | typedef int64_t SkFixed3232;   // 32.32 | 
|---|
| 127 |  | 
|---|
| 128 | #define SkFixed3232Max            SK_MaxS64 | 
|---|
| 129 | #define SkFixed3232Min            (-SkFixed3232Max) | 
|---|
| 130 |  | 
|---|
| 131 | #define SkIntToFixed3232(x)       (SkLeftShift((SkFixed3232)(x), 32)) | 
|---|
| 132 | #define SkFixed3232ToInt(x)       ((int)((x) >> 32)) | 
|---|
| 133 | #define SkFixedToFixed3232(x)     (SkLeftShift((SkFixed3232)(x), 16)) | 
|---|
| 134 | #define SkFixed3232ToFixed(x)     ((SkFixed)((x) >> 16)) | 
|---|
| 135 | #define SkFloatToFixed3232(x)     sk_float_saturate2int64((x) * (65536.0f * 65536.0f)) | 
|---|
| 136 | #define SkFixed3232ToFloat(x)     (x * (1 / (65536.0f * 65536.0f))) | 
|---|
| 137 |  | 
|---|
| 138 | #define SkScalarToFixed3232(x)    SkFloatToFixed3232(x) | 
|---|
| 139 |  | 
|---|
| 140 | #endif | 
|---|
| 141 |  | 
|---|