Reland of ix for conic fuzz (patchset #1 id:1 of https://codereview.chromium.org/2361473004/ )

Reason for revert:
Landed suppression in Chrome's LayoutTests/TestExpectations

Original issue's description:
> Revert of fix for conic fuzz (patchset #3 id:40001 of https://codereview.chromium.org/2350263003/ )
>
> Reason for revert:
> See if this fixes the layout tests.
>
> Original issue's description:
> > fix for conic fuzz
> >
> > A fuzzer generates a conic that hangs when drawn.
> > The quads that approximate the conics move up and down
> > in y, confusing the renderer.
> >
> > This fix ensures that the split conic maintains the
> > same y direction as the original conic.
> >
> > R=reed@google.com
> > BUG=647922
> > GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2350263003
> >
> > Committed: https://skia.googlesource.com/skia/+/ac78863acdef4b428aaf66985b80c76d1be0fdea
>
> TBR=reed@google.com
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=647922
>
> Committed: https://skia.googlesource.com/skia/+/08b345588414b861af8a55950e7dc21a1bd85a28

TBR=reed@google.com
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=647922

Review-Url: https://codereview.chromium.org/2359253002
This commit is contained in:
caryclark 2016-09-22 10:24:59 -07:00 committed by Commit bot
parent 08b3455884
commit bac104605e
2 changed files with 46 additions and 0 deletions

View File

@ -1153,6 +1153,12 @@ int SkConic::computeQuadPOW2(SkScalar tol) const {
return pow2;
}
// This was originally developed and tested for pathops: see SkOpTypes.h
// returns true if (a <= b <= c) || (a >= b >= c)
static bool between(SkScalar a, SkScalar b, SkScalar c) {
return (a - b) * (c - b) <= 0;
}
static SkPoint* subdivide(const SkConic& src, SkPoint pts[], int level) {
SkASSERT(level >= 0);
@ -1162,6 +1168,32 @@ static SkPoint* subdivide(const SkConic& src, SkPoint pts[], int level) {
} else {
SkConic dst[2];
src.chop(dst);
const SkScalar startY = src.fPts[0].fY;
const SkScalar endY = src.fPts[2].fY;
if (between(startY, src.fPts[1].fY, endY)) {
// If the input is monotonic and the output is not, the scan converter hangs.
// Ensure that the chopped conics maintain their y-order.
SkScalar midY = dst[0].fPts[2].fY;
if (!between(startY, midY, endY)) {
// If the computed midpoint is outside the ends, move it to the closer one.
SkScalar closerY = SkTAbs(midY - startY) < SkTAbs(midY - endY) ? startY : endY;
dst[0].fPts[2].fY = dst[1].fPts[0].fY = closerY;
}
if (!between(startY, dst[0].fPts[1].fY, dst[0].fPts[2].fY)) {
// If the 1st control is not between the start and end, put it at the start.
// This also reduces the quad to a line.
dst[0].fPts[1].fY = startY;
}
if (!between(dst[1].fPts[0].fY, dst[1].fPts[1].fY, endY)) {
// If the 2nd control is not between the start and end, put it at the end.
// This also reduces the quad to a line.
dst[1].fPts[1].fY = endY;
}
// Verify that all five points are in order.
SkASSERT(between(startY, dst[0].fPts[1].fY, dst[0].fPts[2].fY));
SkASSERT(between(dst[0].fPts[1].fY, dst[0].fPts[2].fY, dst[1].fPts[1].fY));
SkASSERT(between(dst[0].fPts[2].fY, dst[1].fPts[1].fY, endY));
}
--level;
pts = subdivide(dst[0], pts, level);
return subdivide(dst[1], pts, level);

View File

@ -157,6 +157,19 @@ static void test_fuzz_crbug_643933() {
canvas->drawPath(path, paint);
}
static void test_fuzz_crbug_647922() {
auto surface(SkSurface::MakeRasterN32Premul(250, 250));
SkCanvas* canvas = surface->getCanvas();
SkPaint paint;
paint.setAntiAlias(true);
SkPath path;
path.moveTo(0, 0);
path.conicTo(SkBits2Float(0x00003939), SkBits2Float(0x42487fff), // 2.05276e-41f, 50.125f
SkBits2Float(0x48082361), SkBits2Float(0x4408e8e9), // 139406, 547.639f
SkBits2Float(0x4d1ade0f)); // 1.6239e+08f
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.
@ -4275,6 +4288,7 @@ DEF_TEST(PathContains, reporter) {
}
DEF_TEST(Paths, reporter) {
test_fuzz_crbug_647922();
test_fuzz_crbug_643933();
test_sect_with_horizontal_needs_pinning();
test_crbug_629455(reporter);