GrTessellator: missing intersection rewind fix.

Some "missing" intersections (see
https://skia.googlesource.com/skia/+/89042d5f13a56d6b663657aa58f17593123a344e)
cause the active edge list to go out of order. In that case, we need
to rewind the active list, just as we do before edge splitting for
regular intersections.

BUG=860453

Change-Id: I1f7b32157a73b427a4fd94c14c1eb440f26c0743
Reviewed-on: https://skia-review.googlesource.com/141038
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
Stephen White 2018-07-12 15:54:05 -04:00 committed by Skia Commit-Bot
parent 9cdbf1942d
commit 1c5fd18927
2 changed files with 24 additions and 0 deletions

View File

@ -1110,21 +1110,28 @@ bool intersect_edge_pair(Edge* left, Edge* right, EdgeList* activeEdges, Vertex*
if (!left->fTop || !left->fBottom || !right->fTop || !right->fBottom) { if (!left->fTop || !left->fBottom || !right->fTop || !right->fBottom) {
return false; return false;
} }
if (left->fTop == right->fTop || left->fBottom == right->fBottom) {
return false;
}
if (c.sweep_lt(left->fTop->fPoint, right->fTop->fPoint)) { if (c.sweep_lt(left->fTop->fPoint, right->fTop->fPoint)) {
if (!left->isLeftOf(right->fTop)) { if (!left->isLeftOf(right->fTop)) {
rewind(activeEdges, current, right->fTop, c);
return split_edge(left, right->fTop, activeEdges, current, c, alloc); return split_edge(left, right->fTop, activeEdges, current, c, alloc);
} }
} else { } else {
if (!right->isRightOf(left->fTop)) { if (!right->isRightOf(left->fTop)) {
rewind(activeEdges, current, left->fTop, c);
return split_edge(right, left->fTop, activeEdges, current, c, alloc); return split_edge(right, left->fTop, activeEdges, current, c, alloc);
} }
} }
if (c.sweep_lt(right->fBottom->fPoint, left->fBottom->fPoint)) { if (c.sweep_lt(right->fBottom->fPoint, left->fBottom->fPoint)) {
if (!left->isLeftOf(right->fBottom)) { if (!left->isLeftOf(right->fBottom)) {
rewind(activeEdges, current, right->fBottom, c);
return split_edge(left, right->fBottom, activeEdges, current, c, alloc); return split_edge(left, right->fBottom, activeEdges, current, c, alloc);
} }
} else { } else {
if (!right->isRightOf(left->fBottom)) { if (!right->isRightOf(left->fBottom)) {
rewind(activeEdges, current, left->fBottom, c);
return split_edge(right, left->fBottom, activeEdges, current, c, alloc); return split_edge(right, left->fBottom, activeEdges, current, c, alloc);
} }
} }

View File

@ -584,6 +584,22 @@ static SkPath create_path_40() {
return path; return path;
} }
// Reduction from crbug.com/860453. Tests a case where a "missing" intersection
// requires the active edge list to go out-of-order.
static SkPath create_path_41() {
SkPath path;
path.moveTo(72154931603311689728.0, 330.95965576171875);
path.lineTo(24053266013925408768.0, 78.11376953125);
path.lineTo(1.2031099003292404941e+20, 387.168731689453125);
path.lineTo(68859835992355373056.0, 346.55047607421875);
path.lineTo(76451708695451009024.0, 337.780029296875);
path.moveTo(-20815817797613387776.0, 18065700622522384384.0);
path.lineTo(-72144121204987396096.0, 142.855804443359375);
path.lineTo(72144121204987396096.0, 325.184783935546875);
path.lineTo(1.2347242901040791552e+20, 18065700622522384384.0);
return path;
}
static std::unique_ptr<GrFragmentProcessor> create_linear_gradient_processor(GrContext* ctx) { static std::unique_ptr<GrFragmentProcessor> create_linear_gradient_processor(GrContext* ctx) {
SkPoint pts[2] = { {0, 0}, {1, 1} }; SkPoint pts[2] = { {0, 0}, {1, 1} };
@ -684,4 +700,5 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(TessellatingPathRendererTests, reporter, ctxInfo) {
test_path(ctx, rtc.get(), create_path_38(), SkMatrix(), GrAAType::kCoverage); test_path(ctx, rtc.get(), create_path_38(), SkMatrix(), GrAAType::kCoverage);
test_path(ctx, rtc.get(), create_path_39()); test_path(ctx, rtc.get(), create_path_39());
test_path(ctx, rtc.get(), create_path_40()); test_path(ctx, rtc.get(), create_path_40());
test_path(ctx, rtc.get(), create_path_41(), SkMatrix(), GrAAType::kCoverage);
} }