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

Unified 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, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/effects/gradients/SkClampRange.h ('k') | src/effects/gradients/SkLinearGradient.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/effects/gradients/SkClampRange.cpp
diff --git a/src/effects/gradients/SkClampRange.cpp b/src/effects/gradients/SkClampRange.cpp
index 4f8611281a30607376eb63b227f2809120d2e553..0bf30f14eafda9b480f13a8a5a23b8cd2210851f 100644
--- a/src/effects/gradients/SkClampRange.cpp
+++ b/src/effects/gradients/SkClampRange.cpp
@@ -1,4 +1,3 @@
-
/*
* Copyright 2011 Google Inc.
*
@@ -6,8 +5,33 @@
* found in the LICENSE file.
*/
-
#include "SkClampRange.h"
+#include "SkMath.h"
+
+static int SkCLZ64(uint64_t value) {
+ int count = 0;
+ if (value >> 32) {
+ value >>= 32;
+ } else {
+ count += 32;
+ }
+ return count + SkCLZ(SkToU32(value));
+}
+
+static bool sk_64_smul_check(int64_t a, int64_t b, int64_t* result) {
+ // Do it the slow way until we have some assembly.
+ int64_t ua = SkTAbs(a);
+ int64_t ub = SkTAbs(b);
+ int zeros = SkCLZ64(ua) + SkCLZ64(ub);
+ // this is a conservative check: it may return false when in fact it would not have overflowed.
+ // Hackers Delight uses 34 as its convervative check, but that is for 32x32 multiplies.
+ // Since we are looking at 64x64 muls, we add 32 to the check.
+ if (zeros < (32 + 34)) {
+ return false;
+ }
+ *result = a * b;
+ return true;
+}
/*
* returns [0..count] for the number of steps (<= count) for which x0 <= edge
@@ -58,6 +82,14 @@ void SkClampRange::init(SkGradFixed fx0, SkGradFixed dx0, int count, int v0, int
int64_t dx = dx0;
// start with ex equal to the last computed value
+ int64_t count_times_dx;
+ if (!sk_64_smul_check(count - 1, dx, &count_times_dx)) {
+ // we can't represent the computed end in 32.32, so just draw something (first color)
+ fCount1 = fCount2 = 0;
+ fCount0 = count;
+ return;
+ }
+
int64_t ex = fx + (count - 1) * dx;
if ((uint64_t)(fx | ex) <= kFracMax_SkGradFixed) {
@@ -77,8 +109,6 @@ void SkClampRange::init(SkGradFixed fx0, SkGradFixed dx0, int count, int v0, int
return;
}
- int extraCount = 0;
-
// now make ex be 1 past the last computed value
ex += dx;
@@ -93,11 +123,15 @@ void SkClampRange::init(SkGradFixed fx0, SkGradFixed dx0, int count, int v0, int
fCount0 = chop(fx, 0, ex, dx, count);
+ SkASSERT(fCount0 >= 0);
+ SkASSERT(fCount0 <= count);
count -= fCount0;
fx += fCount0 * dx;
SkASSERT(fx >= 0);
SkASSERT(fCount0 == 0 || (fx - dx) < 0);
fCount1 = chop(fx, kFracMax_SkGradFixed, ex, dx, count);
+ SkASSERT(fCount1 >= 0);
+ SkASSERT(fCount1 <= count);
count -= fCount1;
fCount2 = count;
@@ -121,10 +155,4 @@ void SkClampRange::init(SkGradFixed fx0, SkGradFixed dx0, int count, int v0, int
if (fCount1 > 0) {
fFx1 = fx0 + fCount0 * dx;
}
-
- if (dx > 0) {
- fCount2 += extraCount;
- } else {
- fCount0 += extraCount;
- }
}
« 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