GrTessellator: fix overlap outer boundary winding.

When two outer boundary edges are collinear, they are part of an
overlap region. As of 77169c8fd6, we (correctly) leave these edges
connected, but we must also adjust the winding to magnitude 1 to
keep the winding rules correct.

Note: this adds a new test case to the concavepaths GM, affecting all platforms.

Bug: 863389

Change-Id: I7e3a06df537cd189101e7ad39a4815a78be8fbdd
Reviewed-on: https://skia-review.googlesource.com/141952
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
Stephen White 2018-07-17 16:14:31 -04:00 committed by Skia Commit-Bot
parent 5dbb0c3db5
commit 85dcf6bf80
2 changed files with 18 additions and 0 deletions

View File

@ -367,6 +367,22 @@ void test_bowtie_coincident_triangle(SkCanvas* canvas, const SkPaint& paint) {
canvas->restore();
}
// Collinear outer boundary edges. In the edge-AA codepath, this creates an overlap region
// which contains a boundary edge. It can't be removed, but it must have the correct winding.
void test_collinear_outer_boundary_edge(SkCanvas* canvas, const SkPaint& paint) {
SkPath path;
canvas->save();
canvas->translate(400, 400);
path.moveTo(20, 20);
path.lineTo(20, 50);
path.lineTo(50, 50);
path.moveTo(80, 50);
path.lineTo(50, 50);
path.lineTo(80, 20);
canvas->drawPath(path, paint);
canvas->restore();
}
// Coincident edges (big ones first, coincident vert on top).
void test_coincident_edges_1(SkCanvas* canvas, const SkPaint& paint) {
SkPath path;
@ -456,6 +472,7 @@ DEF_SIMPLE_GM(concavepaths, canvas, 500, 600) {
test_degenerate(canvas, paint);
test_coincident_edge(canvas, paint);
test_bowtie_coincident_triangle(canvas, paint);
test_collinear_outer_boundary_edge(canvas, paint);
test_coincident_edges_1(canvas, paint);
test_coincident_edges_2(canvas, paint);
test_coincident_edges_3(canvas, paint);

View File

@ -1785,6 +1785,7 @@ void Event::apply(VertexList* mesh, Comparator& c, SkArenaAlloc& alloc) {
} else {
LOG("edge %g -> %g is outer boundary; not disconnecting.\n",
fEdge->fTop->fID, fEdge->fBottom->fID);
fEdge->fWinding = fEdge->fWinding >= 0 ? 1 : -1;
}
// If top still has some connected edges, set its partner to dest.