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
This commit is contained in:
liyuqian 2016-10-28 17:16:53 -07:00 committed by Commit bot
parent 1f05f44e8f
commit a3316adf63

View File

@ -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).