| 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 |