aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Stephen White <senorblanco@chromium.org>2017-02-03 10:15:16 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-03 15:47:07 +0000
commit48ded38da99c1171ba1bb469f6500f8214e9105c (patch)
tree436983de2d33153e7eefe22ec9c0c8faf9590efc /src
parent0f90668c122ba4c9a39b57a9b3d0880e3feb5e17 (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.cpp17
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);