| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2006 The Android Open Source Project | 2  * Copyright 2006 The Android Open Source Project | 
| 3  * | 3  * | 
| 4  * Use of this source code is governed by a BSD-style license that can be | 4  * Use of this source code is governed by a BSD-style license that can be | 
| 5  * found in the LICENSE file. | 5  * found in the LICENSE file. | 
| 6  */ | 6  */ | 
| 7 | 7 | 
| 8 #ifndef SkFixed_DEFINED | 8 #ifndef SkFixed_DEFINED | 
| 9 #define SkFixed_DEFINED | 9 #define SkFixed_DEFINED | 
| 10 | 10 | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 24 #define SK_Fixed1           (1 << 16) | 24 #define SK_Fixed1           (1 << 16) | 
| 25 #define SK_FixedHalf        (1 << 15) | 25 #define SK_FixedHalf        (1 << 15) | 
| 26 #define SK_FixedMax         (0x7FFFFFFF) | 26 #define SK_FixedMax         (0x7FFFFFFF) | 
| 27 #define SK_FixedMin         (-SK_FixedMax) | 27 #define SK_FixedMin         (-SK_FixedMax) | 
| 28 #define SK_FixedPI          (0x3243F) | 28 #define SK_FixedPI          (0x3243F) | 
| 29 #define SK_FixedSqrt2       (92682) | 29 #define SK_FixedSqrt2       (92682) | 
| 30 #define SK_FixedTanPIOver8  (0x6A0A) | 30 #define SK_FixedTanPIOver8  (0x6A0A) | 
| 31 #define SK_FixedRoot2Over2  (0xB505) | 31 #define SK_FixedRoot2Over2  (0xB505) | 
| 32 | 32 | 
| 33 #define SkFixedToFloat(x)   ((x) * 1.52587890625e-5f) | 33 #define SkFixedToFloat(x)   ((x) * 1.52587890625e-5f) | 
| 34 #define SkFloatToFixed(x)   ((SkFixed)((x) * SK_Fixed1)) | 34 | 
|  | 35 /////////////////////////////////////////////////////////////////////////////// | 
|  | 36 // ASM alternatives for our portable versions. | 
|  | 37 | 
|  | 38 #if defined(SK_CPU_ARM32) | 
|  | 39     /* This guy does not handle NaN or other obscurities, but is faster than | 
|  | 40        than (int)(x*65536).  When built on Android with -Os, needs forcing | 
|  | 41        to inline or we lose the speed benefit. | 
|  | 42     */ | 
|  | 43     SK_ALWAYS_INLINE SkFixed SkFloatToFixed_arm(float x) | 
|  | 44     { | 
|  | 45         int32_t y, z; | 
|  | 46         asm("movs    %1, %3, lsl #1         \n" | 
|  | 47             "mov     %2, #0x8E              \n" | 
|  | 48             "sub     %1, %2, %1, lsr #24    \n" | 
|  | 49             "mov     %2, %3, lsl #8         \n" | 
|  | 50             "orr     %2, %2, #0x80000000    \n" | 
|  | 51             "mov     %1, %2, lsr %1         \n" | 
|  | 52             "it cs                          \n" | 
|  | 53             "rsbcs   %1, %1, #0             \n" | 
|  | 54             : "=r"(x), "=&r"(y), "=&r"(z) | 
|  | 55             : "r"(x) | 
|  | 56             : "cc" | 
|  | 57             ); | 
|  | 58         return y; | 
|  | 59     } | 
|  | 60     inline SkFixed SkFixedMul_arm(SkFixed x, SkFixed y) | 
|  | 61     { | 
|  | 62         int32_t t; | 
|  | 63         asm("smull  %0, %2, %1, %3          \n" | 
|  | 64             "mov    %0, %0, lsr #16         \n" | 
|  | 65             "orr    %0, %0, %2, lsl #16     \n" | 
|  | 66             : "=r"(x), "=&r"(y), "=r"(t) | 
|  | 67             : "r"(x), "1"(y) | 
|  | 68             : | 
|  | 69             ); | 
|  | 70         return x; | 
|  | 71     } | 
|  | 72 | 
|  | 73     #define SkFixedMul(x, y)           SkFixedMul_arm(x, y) | 
|  | 74     #define SkFloatToFixed_Unsafe(x)   SkFloatToFixed_arm(x) | 
|  | 75 #else | 
|  | 76     inline SkFixed SkFixedMul_longlong(SkFixed a, SkFixed b) { | 
|  | 77         return (SkFixed)((int64_t)a * b >> 16); | 
|  | 78     } | 
|  | 79 | 
|  | 80     #define SkFixedMul(x, y)           SkFixedMul_longlong(x, y) | 
|  | 81     #define SkFloatToFixed_Unsafe(x)   ((SkFixed)((x) * SK_Fixed1)) | 
|  | 82 #endif | 
|  | 83 | 
|  | 84 /////////////////////////////////////////////////////////////////////////////// | 
|  | 85 | 
|  | 86 static inline SkFixed SkFloatToFixed(float x) { | 
|  | 87     const SkFixed result = SkFloatToFixed_Unsafe(x); | 
|  | 88     SkASSERT(truncf(x * SK_Fixed1) == static_cast<float>(result)); | 
|  | 89     return result; | 
|  | 90 } | 
| 35 | 91 | 
| 36 // Pins over/under flows to SK_FixedMax/SK_FixedMin (slower than just a cast). | 92 // Pins over/under flows to SK_FixedMax/SK_FixedMin (slower than just a cast). | 
| 37 static inline SkFixed SkFloatPinToFixed(float x) { | 93 static inline SkFixed SkFloatPinToFixed(float x) { | 
| 38     x *= SK_Fixed1; | 94     x *= SK_Fixed1; | 
| 39     // Casting float to int outside the range of the target type (int32_t) is un
     defined behavior. | 95     // Casting float to int outside the range of the target type (int32_t) is un
     defined behavior. | 
| 40     if (x >= SK_FixedMax) return SK_FixedMax; | 96     if (x >= SK_FixedMax) return SK_FixedMax; | 
| 41     if (x <= SK_FixedMin) return SK_FixedMin; | 97     if (x <= SK_FixedMin) return SK_FixedMin; | 
| 42     const SkFixed result = static_cast<SkFixed>(x); | 98     const SkFixed result = static_cast<SkFixed>(x); | 
| 43     SkASSERT(truncf(x) == static_cast<float>(result)); | 99     SkASSERT(truncf(x) == static_cast<float>(result)); | 
| 44     return result; | 100     return result; | 
| 45 } | 101 } | 
| 46 | 102 | 
| 47 #ifdef SK_DEBUG | 103 #define SkFixedToDouble(x)         ((x) * 1.52587890625e-5) | 
| 48     static inline SkFixed SkFloatToFixed_Check(float x) { | 104 #define SkDoubleToFixed_Unsafe(x)  ((SkFixed)((x) * SK_Fixed1)) | 
| 49         int64_t n64 = (int64_t)(x * SK_Fixed1); |  | 
| 50         SkFixed n32 = (SkFixed)n64; |  | 
| 51         SkASSERT(n64 == n32); |  | 
| 52         return n32; |  | 
| 53     } |  | 
| 54 #else |  | 
| 55     #define SkFloatToFixed_Check(x) SkFloatToFixed(x) |  | 
| 56 #endif |  | 
| 57 | 105 | 
| 58 #define SkFixedToDouble(x)  ((x) * 1.52587890625e-5) | 106 static inline SkFixed SkDoubleToFixed(double x) { | 
| 59 #define SkDoubleToFixed(x)  ((SkFixed)((x) * SK_Fixed1)) | 107     const SkFixed result = SkDoubleToFixed_Unsafe(x); | 
|  | 108     SkASSERT(trunc(x * SK_Fixed1) == static_cast<double>(result)); | 
|  | 109     return result; | 
|  | 110 } | 
| 60 | 111 | 
| 61 // Pins over/under flows to SK_FixedMax/SK_FixedMin (slower than just a cast). | 112 // Pins over/under flows to SK_FixedMax/SK_FixedMin (slower than just a cast). | 
| 62 static inline SkFixed SkDoublePinToFixed(double x) { | 113 static inline SkFixed SkDoublePinToFixed(double x) { | 
| 63     x *= SK_Fixed1; | 114     x *= SK_Fixed1; | 
| 64     // Casting double to int outside the range of the target type (int32_t) is u
     ndefined behavior. | 115     // Casting double to int outside the range of the target type (int32_t) is u
     ndefined behavior. | 
| 65     if (x >= SK_FixedMax) return SK_FixedMax; | 116     if (x >= SK_FixedMax) return SK_FixedMax; | 
| 66     if (x <= SK_FixedMin) return SK_FixedMin; | 117     if (x <= SK_FixedMin) return SK_FixedMin; | 
| 67     const SkFixed result = static_cast<SkFixed>(x); | 118     const SkFixed result = static_cast<SkFixed>(x); | 
| 68     SkASSERT(trunc(x) == static_cast<double>(result)); | 119     SkASSERT(trunc(x) == static_cast<double>(result)); | 
| 69     return result; | 120     return result; | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
| 100 | 151 | 
| 101 // Blink layout tests are baselined to Clang optimizing through undefined behavi
     or in SkDivBits. | 152 // Blink layout tests are baselined to Clang optimizing through undefined behavi
     or in SkDivBits. | 
| 102 #if defined(SK_SUPPORT_LEGACY_DIVBITS_UB) | 153 #if defined(SK_SUPPORT_LEGACY_DIVBITS_UB) | 
| 103     #define SkFixedDiv(numer, denom) SkDivBits(numer, denom, 16) | 154     #define SkFixedDiv(numer, denom) SkDivBits(numer, denom, 16) | 
| 104 #else | 155 #else | 
| 105     // The divide may exceed 32 bits. Clamp to a signed 32 bit result. | 156     // The divide may exceed 32 bits. Clamp to a signed 32 bit result. | 
| 106     #define SkFixedDiv(numer, denom) \ | 157     #define SkFixedDiv(numer, denom) \ | 
| 107         SkToS32(SkTPin<int64_t>((SkLeftShift((int64_t)numer, 16) / denom), SK_Mi
     nS32, SK_MaxS32)) | 158         SkToS32(SkTPin<int64_t>((SkLeftShift((int64_t)numer, 16) / denom), SK_Mi
     nS32, SK_MaxS32)) | 
| 108 #endif | 159 #endif | 
| 109 | 160 | 
| 110 ////////////////////////////////////////////////////////////////////////////////
     ////////////////////// |  | 
| 111 // Now look for ASM overrides for our portable versions (should consider putting
      this in its own file) |  | 
| 112 |  | 
| 113 inline SkFixed SkFixedMul_longlong(SkFixed a, SkFixed b) { |  | 
| 114     return (SkFixed)((int64_t)a * b >> 16); |  | 
| 115 } |  | 
| 116 #define SkFixedMul(a,b)     SkFixedMul_longlong(a,b) |  | 
| 117 |  | 
| 118 |  | 
| 119 #if defined(SK_CPU_ARM32) |  | 
| 120     /* This guy does not handle NaN or other obscurities, but is faster than |  | 
| 121        than (int)(x*65536).  When built on Android with -Os, needs forcing |  | 
| 122        to inline or we lose the speed benefit. |  | 
| 123     */ |  | 
| 124     SK_ALWAYS_INLINE SkFixed SkFloatToFixed_arm(float x) |  | 
| 125     { |  | 
| 126         int32_t y, z; |  | 
| 127         asm("movs    %1, %3, lsl #1         \n" |  | 
| 128             "mov     %2, #0x8E              \n" |  | 
| 129             "sub     %1, %2, %1, lsr #24    \n" |  | 
| 130             "mov     %2, %3, lsl #8         \n" |  | 
| 131             "orr     %2, %2, #0x80000000    \n" |  | 
| 132             "mov     %1, %2, lsr %1         \n" |  | 
| 133             "it cs                          \n" |  | 
| 134             "rsbcs   %1, %1, #0             \n" |  | 
| 135             : "=r"(x), "=&r"(y), "=&r"(z) |  | 
| 136             : "r"(x) |  | 
| 137             : "cc" |  | 
| 138             ); |  | 
| 139         return y; |  | 
| 140     } |  | 
| 141     inline SkFixed SkFixedMul_arm(SkFixed x, SkFixed y) |  | 
| 142     { |  | 
| 143         int32_t t; |  | 
| 144         asm("smull  %0, %2, %1, %3          \n" |  | 
| 145             "mov    %0, %0, lsr #16         \n" |  | 
| 146             "orr    %0, %0, %2, lsl #16     \n" |  | 
| 147             : "=r"(x), "=&r"(y), "=r"(t) |  | 
| 148             : "r"(x), "1"(y) |  | 
| 149             : |  | 
| 150             ); |  | 
| 151         return x; |  | 
| 152     } |  | 
| 153     #undef SkFixedMul |  | 
| 154     #define SkFixedMul(x, y)        SkFixedMul_arm(x, y) |  | 
| 155 |  | 
| 156     #undef SkFloatToFixed |  | 
| 157     #define SkFloatToFixed(x)  SkFloatToFixed_arm(x) |  | 
| 158 #endif |  | 
| 159 |  | 
| 160 /////////////////////////////////////////////////////////////////////////////// | 161 /////////////////////////////////////////////////////////////////////////////// | 
| 161 | 162 | 
| 162 #if SK_SCALAR_IS_FLOAT | 163 #if SK_SCALAR_IS_FLOAT | 
| 163 | 164 | 
| 164 #define SkFixedToScalar(x)          SkFixedToFloat(x) | 165 #define SkFixedToScalar(x)          SkFixedToFloat(x) | 
| 165 #define SkScalarToFixed(x)          SkFloatToFixed(x) | 166 #define SkScalarToFixed(x)          SkFloatToFixed(x) | 
| 166 #define SkScalarPinToFixed(x)       SkFloatPinToFixed(x) | 167 #define SkScalarPinToFixed(x)       SkFloatPinToFixed(x) | 
| 167 | 168 | 
| 168 #else   // SK_SCALAR_IS_DOUBLE | 169 #else   // SK_SCALAR_IS_DOUBLE | 
| 169 | 170 | 
| 170 #define SkFixedToScalar(x)          SkFixedToDouble(x) | 171 #define SkFixedToScalar(x)          SkFixedToDouble(x) | 
| 171 #define SkScalarToFixed(x)          SkDoubleToFixed(x) | 172 #define SkScalarToFixed(x)          SkDoubleToFixed(x) | 
| 172 #define SkScalarPinToFixed(x)       SkDoublePinToFixed(x) | 173 #define SkScalarPinToFixed(x)       SkDoublePinToFixed(x) | 
| 173 | 174 | 
| 174 #endif | 175 #endif | 
| 175 | 176 | 
| 176 /////////////////////////////////////////////////////////////////////////////// | 177 /////////////////////////////////////////////////////////////////////////////// | 
| 177 | 178 | 
| 178 typedef int64_t SkFixed3232;   // 32.32 | 179 typedef int64_t SkFixed3232;   // 32.32 | 
| 179 | 180 | 
| 180 #define SkIntToFixed3232(x)       (SkLeftShift((SkFixed3232)(x), 32)) | 181 #define SK_Fixed3232_1                (static_cast<SkFixed3232>(1) << 32) | 
| 181 #define SkFixed3232ToInt(x)       ((int)((x) >> 32)) | 182 #define SkIntToFixed3232(x)           (SkLeftShift((SkFixed3232)(x), 32)) | 
| 182 #define SkFixedToFixed3232(x)     (SkLeftShift((SkFixed3232)(x), 16)) | 183 #define SkFixed3232ToInt(x)           ((int)((x) >> 32)) | 
| 183 #define SkFixed3232ToFixed(x)     ((SkFixed)((x) >> 16)) | 184 #define SkFixedToFixed3232(x)         (SkLeftShift((SkFixed3232)(x), 16)) | 
| 184 #define SkFloatToFixed3232(x)     ((SkFixed3232)((x) * (65536.0f * 65536.0f))) | 185 #define SkFixed3232ToFixed(x)         ((SkFixed)((x) >> 16)) | 
|  | 186 #define SkFloatToFixed3232_Unsafe(x)  (static_cast<SkFixed3232>((x) * SK_Fixed32
     32_1)) | 
|  | 187 | 
|  | 188 static inline SkFixed3232 SkFloatToFixed3232(float x) { | 
|  | 189     const SkFixed3232 result = SkFloatToFixed3232_Unsafe(x); | 
|  | 190     SkASSERT(truncf(x * SK_Fixed3232_1) == static_cast<float>(result)); | 
|  | 191     return result; | 
|  | 192 } | 
| 185 | 193 | 
| 186 #define SkScalarToFixed3232(x)    SkFloatToFixed3232(x) | 194 #define SkScalarToFixed3232(x)    SkFloatToFixed3232(x) | 
| 187 | 195 | 
| 188 #endif | 196 #endif | 
| OLD | NEW | 
|---|