aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar liyuqian <liyuqian@google.com>2016-10-28 17:16:53 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-10-28 17:16:53 -0700
commita3316adf63ca168c9125df965cfa85bdd7b50a1c (patch)
tree5117b4f63d636ce33b29963385feec05a51d1c80 /src/core
parent1f05f44e8fc0d54afdda04c8e2b846ebad5d9d2f (diff)
Prevent overflow by falling back to non-AA
This piece of code is directly copied from our old supersampling AA code. I didn not preserve this code because it's not triggered by any Skia tests. However, this will be critical to Chromium's tests as some websites will generate huge paths! I'm not so sure whether the long_running_idle_gmail_background_tbmv2 test failed because of this. But I'm sure that www.nationalgeographic.com from page_cycler_v2.typical_25 failed because of this. BUG=chromium:660394 TBR=reed@google.com,caryclark@google.com GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2461133002 Review-Url: https://codereview.chromium.org/2461133002
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkScan_AAAPath.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/core/SkScan_AAAPath.cpp b/src/core/SkScan_AAAPath.cpp
index 1513ce7760..c3bc9f30bc 100644
--- a/src/core/SkScan_AAAPath.cpp
+++ b/src/core/SkScan_AAAPath.cpp
@@ -1212,6 +1212,29 @@ void SkScan::aaa_fill_path(const SkPath& path, const SkIRect* clipRect, Additive
///////////////////////////////////////////////////////////////////////////////
+static int overflows_short_shift(int value, int shift) {
+ const int s = 16 + shift;
+ return (SkLeftShift(value, s) >> s) - value;
+}
+
+/**
+ Would any of the coordinates of this rectangle not fit in a short,
+ when left-shifted by shift?
+*/
+static int rect_overflows_short_shift(SkIRect rect, int shift) {
+ SkASSERT(!overflows_short_shift(8191, 2));
+ SkASSERT(overflows_short_shift(8192, 2));
+ SkASSERT(!overflows_short_shift(32767, 0));
+ SkASSERT(overflows_short_shift(32768, 0));
+
+ // Since we expect these to succeed, we bit-or together
+ // for a tiny extra bit of speed.
+ return overflows_short_shift(rect.fLeft, 2) |
+ overflows_short_shift(rect.fRight, 2) |
+ overflows_short_shift(rect.fTop, 2) |
+ overflows_short_shift(rect.fBottom, 2);
+}
+
void SkScan::AAAFillPath(const SkPath& path, const SkRegion& origClip, SkBlitter* blitter,
bool forceRLE) {
if (origClip.isEmpty()) {
@@ -1243,6 +1266,13 @@ void SkScan::AAAFillPath(const SkPath& path, const SkRegion& origClip, SkBlitter
return;
}
}
+ // If the intersection of the path bounds and the clip bounds
+ // will overflow 32767 when << by 2, our SkFixed will overflow,
+ // so draw without antialiasing.
+ if (rect_overflows_short_shift(clippedIR, 2)) {
+ SkScan::FillPath(path, origClip, blitter);
+ return;
+ }
// Our antialiasing can't handle a clip larger than 32767, so we restrict
// the clip to that limit here. (the runs[] uses int16_t for its index).