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

Side by Side Diff: src/effects/gradients/SkClampRange.cpp

Issue 886473003: add more checks for computing clamp counts, remove dead code (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: update comment on overflow test Created 5 years, 10 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 | « src/effects/gradients/SkClampRange.h ('k') | src/effects/gradients/SkLinearGradient.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1
2 /* 1 /*
3 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
4 * 3 *
5 * 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
6 * found in the LICENSE file. 5 * found in the LICENSE file.
7 */ 6 */
8 7
8 #include "SkClampRange.h"
9 #include "SkMath.h"
9 10
10 #include "SkClampRange.h" 11 static int SkCLZ64(uint64_t value) {
12 int count = 0;
13 if (value >> 32) {
14 value >>= 32;
15 } else {
16 count += 32;
17 }
18 return count + SkCLZ(SkToU32(value));
19 }
20
21 static bool sk_64_smul_check(int64_t a, int64_t b, int64_t* result) {
22 // Do it the slow way until we have some assembly.
23 int64_t ua = SkTAbs(a);
24 int64_t ub = SkTAbs(b);
25 int zeros = SkCLZ64(ua) + SkCLZ64(ub);
26 // this is a conservative check: it may return false when in fact it would n ot have overflowed.
27 // Hackers Delight uses 34 as its convervative check, but that is for 32x32 multiplies.
28 // Since we are looking at 64x64 muls, we add 32 to the check.
29 if (zeros < (32 + 34)) {
30 return false;
31 }
32 *result = a * b;
33 return true;
34 }
11 35
12 /* 36 /*
13 * returns [0..count] for the number of steps (<= count) for which x0 <= edge 37 * returns [0..count] for the number of steps (<= count) for which x0 <= edge
14 * given each step is followed by x0 += dx 38 * given each step is followed by x0 += dx
15 */ 39 */
16 static int chop(int64_t x0, SkGradFixed edge, int64_t x1, int64_t dx, int count) { 40 static int chop(int64_t x0, SkGradFixed edge, int64_t x1, int64_t dx, int count) {
17 SkASSERT(dx > 0); 41 SkASSERT(dx > 0);
18 SkASSERT(count >= 0); 42 SkASSERT(count >= 0);
19 43
20 if (x0 >= edge) { 44 if (x0 >= edge) {
(...skipping 30 matching lines...) Expand all
51 // and avoids us ever calling divide or 64bit multiply 75 // and avoids us ever calling divide or 64bit multiply
52 if (1 == count) { 76 if (1 == count) {
53 this->initFor1(fx0); 77 this->initFor1(fx0);
54 return; 78 return;
55 } 79 }
56 80
57 int64_t fx = fx0; 81 int64_t fx = fx0;
58 int64_t dx = dx0; 82 int64_t dx = dx0;
59 83
60 // start with ex equal to the last computed value 84 // start with ex equal to the last computed value
85 int64_t count_times_dx;
86 if (!sk_64_smul_check(count - 1, dx, &count_times_dx)) {
87 // we can't represent the computed end in 32.32, so just draw something (first color)
88 fCount1 = fCount2 = 0;
89 fCount0 = count;
90 return;
91 }
92
61 int64_t ex = fx + (count - 1) * dx; 93 int64_t ex = fx + (count - 1) * dx;
62 94
63 if ((uint64_t)(fx | ex) <= kFracMax_SkGradFixed) { 95 if ((uint64_t)(fx | ex) <= kFracMax_SkGradFixed) {
64 fCount0 = fCount2 = 0; 96 fCount0 = fCount2 = 0;
65 fCount1 = count; 97 fCount1 = count;
66 fFx1 = fx0; 98 fFx1 = fx0;
67 return; 99 return;
68 } 100 }
69 if (fx <= 0 && ex <= 0) { 101 if (fx <= 0 && ex <= 0) {
70 fCount1 = fCount2 = 0; 102 fCount1 = fCount2 = 0;
71 fCount0 = count; 103 fCount0 = count;
72 return; 104 return;
73 } 105 }
74 if (fx >= kFracMax_SkGradFixed && ex >= kFracMax_SkGradFixed) { 106 if (fx >= kFracMax_SkGradFixed && ex >= kFracMax_SkGradFixed) {
75 fCount0 = fCount1 = 0; 107 fCount0 = fCount1 = 0;
76 fCount2 = count; 108 fCount2 = count;
77 return; 109 return;
78 } 110 }
79 111
80 int extraCount = 0;
81
82 // now make ex be 1 past the last computed value 112 // now make ex be 1 past the last computed value
83 ex += dx; 113 ex += dx;
84 114
85 bool doSwap = dx < 0; 115 bool doSwap = dx < 0;
86 116
87 if (doSwap) { 117 if (doSwap) {
88 ex -= dx; 118 ex -= dx;
89 fx -= dx; 119 fx -= dx;
90 SkTSwap(fx, ex); 120 SkTSwap(fx, ex);
91 dx = -dx; 121 dx = -dx;
92 } 122 }
93 123
94 124
95 fCount0 = chop(fx, 0, ex, dx, count); 125 fCount0 = chop(fx, 0, ex, dx, count);
126 SkASSERT(fCount0 >= 0);
127 SkASSERT(fCount0 <= count);
96 count -= fCount0; 128 count -= fCount0;
97 fx += fCount0 * dx; 129 fx += fCount0 * dx;
98 SkASSERT(fx >= 0); 130 SkASSERT(fx >= 0);
99 SkASSERT(fCount0 == 0 || (fx - dx) < 0); 131 SkASSERT(fCount0 == 0 || (fx - dx) < 0);
100 fCount1 = chop(fx, kFracMax_SkGradFixed, ex, dx, count); 132 fCount1 = chop(fx, kFracMax_SkGradFixed, ex, dx, count);
133 SkASSERT(fCount1 >= 0);
134 SkASSERT(fCount1 <= count);
101 count -= fCount1; 135 count -= fCount1;
102 fCount2 = count; 136 fCount2 = count;
103 137
104 #ifdef SK_DEBUG 138 #ifdef SK_DEBUG
105 fx += fCount1 * dx; 139 fx += fCount1 * dx;
106 SkASSERT(fx <= ex); 140 SkASSERT(fx <= ex);
107 if (fCount2 > 0) { 141 if (fCount2 > 0) {
108 SkASSERT(fx >= kFracMax_SkGradFixed); 142 SkASSERT(fx >= kFracMax_SkGradFixed);
109 if (fCount1 > 0) { 143 if (fCount1 > 0) {
110 SkASSERT(fx - dx < kFracMax_SkGradFixed); 144 SkASSERT(fx - dx < kFracMax_SkGradFixed);
111 } 145 }
112 } 146 }
113 #endif 147 #endif
114 148
115 if (doSwap) { 149 if (doSwap) {
116 SkTSwap(fCount0, fCount2); 150 SkTSwap(fCount0, fCount2);
117 SkTSwap(fV0, fV1); 151 SkTSwap(fV0, fV1);
118 dx = -dx; 152 dx = -dx;
119 } 153 }
120 154
121 if (fCount1 > 0) { 155 if (fCount1 > 0) {
122 fFx1 = fx0 + fCount0 * dx; 156 fFx1 = fx0 + fCount0 * dx;
123 } 157 }
124
125 if (dx > 0) {
126 fCount2 += extraCount;
127 } else {
128 fCount0 += extraCount;
129 }
130 } 158 }
OLDNEW
« no previous file with comments | « src/effects/gradients/SkClampRange.h ('k') | src/effects/gradients/SkLinearGradient.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698