Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: include/private/SkFixed.h

Issue 1824733002: For *ToFixed, in debug mode, assert that the value is in range. (Closed) Base URL: https://skia.googlesource.com/skia@scalar-pin-to-fixed
Patch Set: Rebase. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/core/SkScan.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « no previous file | src/core/SkScan.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698