Fix mask overflow caused by edge drift
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4797 Change-Id: Ica1568b67c1e1ce4aae2bdaba2c5b1f2155d1382 Reviewed-on: https://skia-review.googlesource.com/4797 Reviewed-by: Cary Clark <caryclark@google.com>
This commit is contained in:
parent
721625b25e
commit
20079a94e8
@ -44,7 +44,7 @@ struct SkAnalyticEdge {
|
||||
|
||||
static inline SkFixed snapY(SkFixed y, int accuracy = kDefaultAccuracy) {
|
||||
// This approach is safer than left shift, round, then right shift
|
||||
return (y + (SK_Fixed1 >> (accuracy + 1))) >> (16 - accuracy) << (16 - accuracy);
|
||||
return ((unsigned)y + (SK_Fixed1 >> (accuracy + 1))) >> (16 - accuracy) << (16 - accuracy);
|
||||
}
|
||||
|
||||
// Update fX, fY of this edge so fY = y
|
||||
|
@ -1204,8 +1204,18 @@ void aaa_fill_path(const SkPath& path, const SkIRect& clipRect, AdditiveBlitter*
|
||||
|
||||
if (!path.isInverseFillType() && path.isConvex()) {
|
||||
SkASSERT(count >= 2); // convex walker does not handle missing right edges
|
||||
SkFixed leftBound = SkIntToFixed(rect.fLeft);
|
||||
SkFixed rightBound = SkIntToFixed(rect.fRight);
|
||||
if (isUsingMask) {
|
||||
// If we're using mask, then we have to limit the bound within the path bounds.
|
||||
// Otherwise, the edge drift may access an invalid address inside the mask.
|
||||
SkIRect ir;
|
||||
path.getBounds().roundOut(&ir);
|
||||
leftBound = SkTMax(leftBound, SkIntToFixed(ir.fLeft));
|
||||
rightBound = SkTMin(rightBound, SkIntToFixed(ir.fRight));
|
||||
}
|
||||
aaa_walk_convex_edges(&headEdge, blitter, start_y, stop_y,
|
||||
rect.fLeft << 16, rect.fRight << 16, isUsingMask);
|
||||
leftBound, rightBound, isUsingMask);
|
||||
} else {
|
||||
SkFAIL("Concave AAA is not yet implemented!");
|
||||
}
|
||||
|
@ -198,6 +198,24 @@ static void test_fuzz_crbug_662780() {
|
||||
canvas->drawRectCoords(0, 0, 250, 250, paint);
|
||||
}
|
||||
|
||||
static void test_mask_overflow() {
|
||||
auto surface(SkSurface::MakeRasterN32Premul(500, 500));
|
||||
SkCanvas* canvas = surface->getCanvas();
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
SkPath path;
|
||||
path.moveTo(SkBits2Float(0x43e28000), SkBits2Float(0x43aa8000)); // 453, 341
|
||||
path.lineTo(SkBits2Float(0x43de6000), SkBits2Float(0x43aa8000)); // 444.75f, 341
|
||||
// 440.47f, 341, 437, 344.47f, 437, 348.75f
|
||||
path.cubicTo(SkBits2Float(0x43dc3c29), SkBits2Float(0x43aa8000),
|
||||
SkBits2Float(0x43da8000), SkBits2Float(0x43ac3c29),
|
||||
SkBits2Float(0x43da8000), SkBits2Float(0x43ae6000));
|
||||
path.lineTo(SkBits2Float(0x43da8000), SkBits2Float(0x43b18000)); // 437, 355
|
||||
path.lineTo(SkBits2Float(0x43e28000), SkBits2Float(0x43b18000)); // 453, 355
|
||||
path.lineTo(SkBits2Float(0x43e28000), SkBits2Float(0x43aa8000)); // 453, 341
|
||||
canvas->drawPath(path, paint);
|
||||
}
|
||||
|
||||
/**
|
||||
* In debug mode, this path was causing an assertion to fail in
|
||||
* SkPathStroker::preJoinTo() and, in Release, the use of an unitialized value.
|
||||
@ -4359,6 +4377,7 @@ DEF_TEST(Paths, reporter) {
|
||||
test_fuzz_crbug_662952(reporter);
|
||||
test_fuzz_crbug_662730(reporter);
|
||||
test_fuzz_crbug_662780();
|
||||
test_mask_overflow();
|
||||
|
||||
SkTSize<SkScalar>::Make(3,4);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user