diff options
author | Stephen White <senorblanco@chromium.org> | 2017-02-03 10:15:16 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-02-03 15:47:07 +0000 |
commit | 48ded38da99c1171ba1bb469f6500f8214e9105c (patch) | |
tree | 436983de2d33153e7eefe22ec9c0c8faf9590efc /src | |
parent | 0f90668c122ba4c9a39b57a9b3d0880e3feb5e17 (diff) |
GrTessellator (AA): Fix for missing fill artifacts.
Some regions were being incorrectly filled due to setting
connector edges winding to zero *after* merging collinear edges.
This would cause the merge to add the wrong winding value. Putting the
adjust before the call to merge_collinear_edges() fixes the problem.
Also, some pixels were not getting coverage due the inner edge being
+1 winding. Using -2 winding for inner edges ensure the interior
regions are -1 winding, which gives coverage in more cases of
self-intersection. This required flipping the comparisons on the
intruding-vertices workaround.
BUG=skia:
Change-Id: I216fa3d30c196a6b7773637e48802f6572c993c7
Reviewed-on: https://skia-review.googlesource.com/7962
Commit-Queue: Stephan White <senorblanco@chromium.org>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrTessellator.cpp | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/src/gpu/GrTessellator.cpp b/src/gpu/GrTessellator.cpp index 9b7aed0b8e..af6fe21e2c 100644 --- a/src/gpu/GrTessellator.cpp +++ b/src/gpu/GrTessellator.cpp @@ -1043,7 +1043,8 @@ void split_edge(Edge* edge, Vertex* v, EdgeList* activeEdges, Comparator& c, SkC } } -Edge* connect(Vertex* prev, Vertex* next, Edge::Type type, Comparator& c, SkChunkAlloc& alloc) { +Edge* connect(Vertex* prev, Vertex* next, Edge::Type type, Comparator& c, SkChunkAlloc& alloc, + int winding_scale = 1) { Edge* edge = new_edge(prev, next, type, c, alloc); if (edge->fWinding > 0) { insert_edge_below(edge, prev, c); @@ -1052,6 +1053,7 @@ Edge* connect(Vertex* prev, Vertex* next, Edge::Type type, Comparator& c, SkChun insert_edge_below(edge, next, c); insert_edge_above(edge, prev, c); } + edge->fWinding *= winding_scale; merge_collinear_edges(edge, nullptr, c); return edge; } @@ -1313,8 +1315,8 @@ void simplify(const VertexList& vertices, Comparator& c, SkChunkAlloc& alloc) { } } while (restartChecks); if (v->fAlpha == 0) { - if ((leftEnclosingEdge && leftEnclosingEdge->fWinding > 0) && - (rightEnclosingEdge && rightEnclosingEdge->fWinding < 0)) { + if ((leftEnclosingEdge && leftEnclosingEdge->fWinding < 0) && + (rightEnclosingEdge && rightEnclosingEdge->fWinding > 0)) { v->fAlpha = max_edge_alpha(leftEnclosingEdge, rightEnclosingEdge); } } @@ -1562,9 +1564,14 @@ void boundary_to_aa_mesh(EdgeList* boundary, VertexList* mesh, Comparator& c, Sk return; } do { + // Connect vertices into a quad mesh. Outer edges get default (1) winding. + // Inner edges get -2 winding. This ensures that the interior is always filled + // (-1 winding number for normal cases, 3 for thin features where the interior inverts). + // Connector edges get zero winding, since they're only structural (i.e., to ensure + // no 0-0-0 alpha triangles are produced), and shouldn't affect the poly winding number. connect(outerVertex->fPrev, outerVertex, Edge::Type::kOuter, c, alloc); - connect(innerVertex->fPrev, innerVertex, Edge::Type::kInner, c, alloc); - connect(outerVertex, innerVertex, Edge::Type::kConnector, c, alloc)->fWinding = 0; + connect(innerVertex->fPrev, innerVertex, Edge::Type::kInner, c, alloc, -2); + connect(outerVertex, innerVertex, Edge::Type::kConnector, c, alloc, 0); Vertex* innerNext = innerVertex->fNext; Vertex* outerNext = outerVertex->fNext; mesh->append(innerVertex); |