OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkClampRange.h" | 10 #include "SkClampRange.h" |
11 | 11 |
12 /* | 12 /* |
13 * returns [0..count] for the number of steps (<= count) for which x0 <= edge | 13 * returns [0..count] for the number of steps (<= count) for which x0 <= edge |
14 * given each step is followed by x0 += dx | 14 * given each step is followed by x0 += dx |
15 */ | 15 */ |
16 static int chop(int64_t x0, SkFixed edge, int64_t x1, int64_t dx, int count) { | 16 static int chop(int64_t x0, SkGradFixed edge, int64_t x1, int64_t dx, int count)
{ |
17 SkASSERT(dx > 0); | 17 SkASSERT(dx > 0); |
18 SkASSERT(count >= 0); | 18 SkASSERT(count >= 0); |
19 | 19 |
20 if (x0 >= edge) { | 20 if (x0 >= edge) { |
21 return 0; | 21 return 0; |
22 } | 22 } |
23 if (x1 <= edge) { | 23 if (x1 <= edge) { |
24 return count; | 24 return count; |
25 } | 25 } |
26 int64_t n = (edge - x0 + dx - 1) / dx; | 26 int64_t n = (edge - x0 + dx - 1) / dx; |
27 SkASSERT(n >= 0); | 27 SkASSERT(n >= 0); |
28 SkASSERT(n <= count); | 28 SkASSERT(n <= count); |
29 return (int)n; | 29 return (int)n; |
30 } | 30 } |
31 | 31 |
32 static bool overflows_fixed(int64_t x) { | 32 #ifdef SK_SUPPORT_LEGACY_GRADIENT_PRECISION |
| 33 static bool overflows_gradfixed(int64_t x) { |
33 return x < -SK_FixedMax || x > SK_FixedMax; | 34 return x < -SK_FixedMax || x > SK_FixedMax; |
34 } | 35 } |
| 36 #endif |
35 | 37 |
36 void SkClampRange::initFor1(SkFixed fx) { | 38 void SkClampRange::initFor1(SkGradFixed fx) { |
37 fCount0 = fCount1 = fCount2 = 0; | 39 fCount0 = fCount1 = fCount2 = 0; |
38 if (fx <= 0) { | 40 if (fx <= 0) { |
39 fCount0 = 1; | 41 fCount0 = 1; |
40 } else if (fx < 0xFFFF) { | 42 } else if (fx < kFracMax_SkGradFixed) { |
41 fCount1 = 1; | 43 fCount1 = 1; |
42 fFx1 = fx; | 44 fFx1 = fx; |
43 } else { | 45 } else { |
44 fCount2 = 1; | 46 fCount2 = 1; |
45 } | 47 } |
46 } | 48 } |
47 | 49 |
48 void SkClampRange::init(SkFixed fx0, SkFixed dx0, int count, int v0, int v1) { | 50 void SkClampRange::init(SkGradFixed fx0, SkGradFixed dx0, int count, int v0, int
v1) { |
49 SkASSERT(count > 0); | 51 SkASSERT(count > 0); |
50 | 52 |
51 fV0 = v0; | 53 fV0 = v0; |
52 fV1 = v1; | 54 fV1 = v1; |
53 | 55 |
54 // special case 1 == count, as it is slightly common for skia | 56 // special case 1 == count, as it is slightly common for skia |
55 // and avoids us ever calling divide or 64bit multiply | 57 // and avoids us ever calling divide or 64bit multiply |
56 if (1 == count) { | 58 if (1 == count) { |
57 this->initFor1(fx0); | 59 this->initFor1(fx0); |
58 return; | 60 return; |
59 } | 61 } |
60 | 62 |
61 int64_t fx = fx0; | 63 int64_t fx = fx0; |
62 int64_t dx = dx0; | 64 int64_t dx = dx0; |
| 65 |
63 // start with ex equal to the last computed value | 66 // start with ex equal to the last computed value |
64 int64_t ex = fx + (count - 1) * dx; | 67 int64_t ex = fx + (count - 1) * dx; |
65 | 68 |
66 if ((uint64_t)(fx | ex) <= 0xFFFF) { | 69 if ((uint64_t)(fx | ex) <= kFracMax_SkGradFixed) { |
67 fCount0 = fCount2 = 0; | 70 fCount0 = fCount2 = 0; |
68 fCount1 = count; | 71 fCount1 = count; |
69 fFx1 = fx0; | 72 fFx1 = fx0; |
70 return; | 73 return; |
71 } | 74 } |
72 if (fx <= 0 && ex <= 0) { | 75 if (fx <= 0 && ex <= 0) { |
73 fCount1 = fCount2 = 0; | 76 fCount1 = fCount2 = 0; |
74 fCount0 = count; | 77 fCount0 = count; |
75 return; | 78 return; |
76 } | 79 } |
77 if (fx >= 0xFFFF && ex >= 0xFFFF) { | 80 if (fx >= kFracMax_SkGradFixed && ex >= kFracMax_SkGradFixed) { |
78 fCount0 = fCount1 = 0; | 81 fCount0 = fCount1 = 0; |
79 fCount2 = count; | 82 fCount2 = count; |
80 return; | 83 return; |
81 } | 84 } |
82 | 85 |
83 int extraCount = 0; | 86 int extraCount = 0; |
84 | 87 |
85 // now make ex be 1 past the last computed value | 88 // now make ex be 1 past the last computed value |
86 ex += dx; | 89 ex += dx; |
| 90 |
| 91 #ifdef SK_SUPPORT_LEGACY_GRADIENT_PRECISION |
87 // now check for over/under flow | 92 // now check for over/under flow |
88 if (overflows_fixed(ex)) { | 93 if (overflows_gradfixed(ex)) { |
89 int originalCount = count; | 94 int originalCount = count; |
90 int64_t ccount; | 95 int64_t ccount; |
91 bool swap = dx < 0; | 96 bool swap = dx < 0; |
92 if (swap) { | 97 if (swap) { |
93 dx = -dx; | 98 dx = -dx; |
94 fx = -fx; | 99 fx = -fx; |
95 } | 100 } |
96 ccount = (SK_FixedMax - fx + dx - 1) / dx; | 101 |
| 102 int shift = 0; |
| 103 if (sizeof(SkGradFixed) == 8) { |
| 104 shift = 16; |
| 105 } |
| 106 |
| 107 ccount = ((SK_FixedMax << shift) - fx + dx - 1) / dx; |
97 if (swap) { | 108 if (swap) { |
98 dx = -dx; | 109 dx = -dx; |
99 fx = -fx; | 110 fx = -fx; |
100 } | 111 } |
101 SkASSERT(ccount > 0 && ccount <= SK_FixedMax); | 112 SkASSERT(ccount > 0 && ccount <= SK_FixedMax); |
102 | 113 |
103 count = (int)ccount; | 114 count = (int)ccount; |
104 if (0 == count) { | 115 if (0 == count) { |
105 this->initFor1(fx0); | 116 this->initFor1(fx0); |
106 if (dx > 0) { | 117 if (dx > 0) { |
107 fCount2 += originalCount - 1; | 118 fCount2 += originalCount - 1; |
108 } else { | 119 } else { |
109 fCount0 += originalCount - 1; | 120 fCount0 += originalCount - 1; |
110 } | 121 } |
111 return; | 122 return; |
112 } | 123 } |
113 extraCount = originalCount - count; | 124 extraCount = originalCount - count; |
114 ex = fx + dx * count; | 125 ex = fx + dx * count; |
115 } | 126 } |
| 127 #endif |
116 | 128 |
117 bool doSwap = dx < 0; | 129 bool doSwap = dx < 0; |
118 | 130 |
119 if (doSwap) { | 131 if (doSwap) { |
120 ex -= dx; | 132 ex -= dx; |
121 fx -= dx; | 133 fx -= dx; |
122 SkTSwap(fx, ex); | 134 SkTSwap(fx, ex); |
123 dx = -dx; | 135 dx = -dx; |
124 } | 136 } |
125 | 137 |
126 | 138 |
127 fCount0 = chop(fx, 0, ex, dx, count); | 139 fCount0 = chop(fx, 0, ex, dx, count); |
128 count -= fCount0; | 140 count -= fCount0; |
129 fx += fCount0 * dx; | 141 fx += fCount0 * dx; |
130 SkASSERT(fx >= 0); | 142 SkASSERT(fx >= 0); |
131 SkASSERT(fCount0 == 0 || (fx - dx) < 0); | 143 SkASSERT(fCount0 == 0 || (fx - dx) < 0); |
132 fCount1 = chop(fx, 0xFFFF, ex, dx, count); | 144 fCount1 = chop(fx, kFracMax_SkGradFixed, ex, dx, count); |
133 count -= fCount1; | 145 count -= fCount1; |
134 fCount2 = count; | 146 fCount2 = count; |
135 | 147 |
136 #ifdef SK_DEBUG | 148 #ifdef SK_DEBUG |
137 fx += fCount1 * dx; | 149 fx += fCount1 * dx; |
138 SkASSERT(fx <= ex); | 150 SkASSERT(fx <= ex); |
139 if (fCount2 > 0) { | 151 if (fCount2 > 0) { |
140 SkASSERT(fx >= 0xFFFF); | 152 SkASSERT(fx >= kFracMax_SkGradFixed); |
141 if (fCount1 > 0) { | 153 if (fCount1 > 0) { |
142 SkASSERT(fx - dx < 0xFFFF); | 154 SkASSERT(fx - dx < kFracMax_SkGradFixed); |
143 } | 155 } |
144 } | 156 } |
145 #endif | 157 #endif |
146 | 158 |
147 if (doSwap) { | 159 if (doSwap) { |
148 SkTSwap(fCount0, fCount2); | 160 SkTSwap(fCount0, fCount2); |
149 SkTSwap(fV0, fV1); | 161 SkTSwap(fV0, fV1); |
150 dx = -dx; | 162 dx = -dx; |
151 } | 163 } |
152 | 164 |
153 if (fCount1 > 0) { | 165 if (fCount1 > 0) { |
154 fFx1 = fx0 + fCount0 * (int)dx; | 166 fFx1 = fx0 + fCount0 * (int)dx; |
155 } | 167 } |
156 | 168 |
157 if (dx > 0) { | 169 if (dx > 0) { |
158 fCount2 += extraCount; | 170 fCount2 += extraCount; |
159 } else { | 171 } else { |
160 fCount0 += extraCount; | 172 fCount0 += extraCount; |
161 } | 173 } |
162 } | 174 } |
OLD | NEW |