GrTessellator: fix for vertex coincident with enclosing edge.

If a previously-enclosing edge coincides exactly with the current 
vertex, there are no two adjacent edges which enclose the vertex.
Since find_enclosing_edges() ensures that the left enclosing edge
is to the left of the vertex, the fix is to split the right 
enclosing edge on the current vertex and restart intersection 
tests.

Bug: 716720
Change-Id: Id26c5b92a6d6139f348e99554638cded37e81a8e
Reviewed-on: https://skia-review.googlesource.com/15261
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
Stephen White 2017-05-03 16:00:38 -04:00 committed by Skia Commit-Bot
parent 0356714916
commit 64dbb89efc
2 changed files with 19 additions and 1 deletions

View File

@ -1267,6 +1267,11 @@ void simplify(const VertexList& vertices, Comparator& c, SkArenaAlloc& alloc) {
do {
restartChecks = false;
find_enclosing_edges(v, &activeEdges, &leftEnclosingEdge, &rightEnclosingEdge);
if (rightEnclosingEdge && !rightEnclosingEdge->isRightOf(v)) {
split_edge(rightEnclosingEdge, v, &activeEdges, c, alloc);
restartChecks = true;
continue;
}
if (v->fFirstEdgeBelow) {
for (Edge* edge = v->fFirstEdgeBelow; edge; edge = edge->fNextEdgeBelow) {
if (check_for_intersection(edge, leftEnclosingEdge, &activeEdges, c, alloc)) {
@ -1395,7 +1400,6 @@ Poly* tessellate(const VertexList& vertices, SkArenaAlloc& alloc) {
}
for (Edge* e = v->fFirstEdgeAbove; e != v->fLastEdgeAbove; e = e->fNextEdgeAbove) {
Edge* rightEdge = e->fNextEdgeAbove;
SkASSERT(rightEdge->isRightOf(e->fTop));
remove_edge(e, &activeEdges);
if (e->fRightPoly) {
e->fRightPoly->addEdge(e, Poly::kLeft_Side, alloc);

View File

@ -261,6 +261,19 @@ static SkPath create_path_17() {
return path;
}
// A shape with a vertex collinear to the right hand edge.
// This messes up find_enclosing_edges.
static SkPath create_path_18() {
SkPath path;
path.moveTo(80, 20);
path.lineTo(80, 60);
path.lineTo(20, 60);
path.moveTo(80, 50);
path.lineTo(80, 80);
path.lineTo(20, 80);
return path;
}
static sk_sp<GrFragmentProcessor> create_linear_gradient_processor(GrContext* ctx) {
SkPoint pts[2] = { {0, 0}, {1, 1} };
SkColor colors[2] = { SK_ColorGREEN, SK_ColorBLUE };
@ -335,5 +348,6 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(TessellatingPathRendererTests, reporter, ctxInfo) {
SkMatrix nonInvertibleMatrix = SkMatrix::MakeScale(0, 0);
sk_sp<GrFragmentProcessor> fp(create_linear_gradient_processor(ctx));
test_path(ctx, rtc.get(), create_path_17(), nonInvertibleMatrix, GrAAType::kCoverage, fp);
test_path(ctx, rtc.get(), create_path_18());
}
#endif