aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrTessellator.cpp
diff options
context:
space:
mode:
authorGravatar Ravi Mistry <rmistry@google.com>2018-05-29 18:19:07 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-29 18:19:17 +0000
commitbfe959872ec7895d4aa6878a9fe189c37dffc99f (patch)
tree7a7ae03b7a1cafd9775d8e918e05902fbe569429 /src/gpu/GrTessellator.cpp
parent862405921bdbf599bac3bd829e9d6a81a4ee4d37 (diff)
Revert "GrTessellator: fix for ping-pong split fuzzer hang."
This reverts commit bfb2a05af105f452a0f369e39dae05f9224dfa19. Reason for revert: Seems to cause failures in chromeos and chromecast test bots. eg: https://chromium-swarm.appspot.com/task?id=3dc5be8269e3b410&refresh=10 https://chromium-swarm.appspot.com/task?id=3dc5d62dfdc99010&refresh=10 Original change's description: > GrTessellator: fix for ping-pong split fuzzer hang. > > Change 3b5a3fa8b1c11d4bd4499b040311f4c3553ebf8c introduced support for > splitting on out-of-range intersections. However, this is only necessary > for correctness when the edge is nearly-flat (the top and bottom > points only differ by 1/2 machine epsilon in the primary sort criterion). > In other cases, it can cause repeated splitting and re-merging of edges, > as the intersection code (being approximate and not exact) may produce a > ping-pong set of intersections. > > The fix is to support out-of-range intersections only if they differ by > 1/2 machine epsilon. This also generalizes the > out_of_range_and_collinear() check, so it was removed. > > Bug: 838978 > Change-Id: I134f7eff3f15707e0d68de11c55f7fadce4ff8e7 > Reviewed-on: https://skia-review.googlesource.com/130448 > Reviewed-by: Robert Phillips <robertphillips@google.com> > Commit-Queue: Stephen White <senorblanco@chromium.org> TBR=robertphillips@google.com,senorblanco@chromium.org Change-Id: I3fa62423d3875665397adcecb94b467b9b6611cc No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: 838978 Reviewed-on: https://skia-review.googlesource.com/130522 Reviewed-by: Ravi Mistry <rmistry@google.com> Commit-Queue: Ravi Mistry <rmistry@google.com>
Diffstat (limited to 'src/gpu/GrTessellator.cpp')
-rw-r--r--src/gpu/GrTessellator.cpp43
1 files changed, 23 insertions, 20 deletions
diff --git a/src/gpu/GrTessellator.cpp b/src/gpu/GrTessellator.cpp
index d69833df2e..4d3c1eb0ee 100644
--- a/src/gpu/GrTessellator.cpp
+++ b/src/gpu/GrTessellator.cpp
@@ -1131,6 +1131,17 @@ void merge_vertices(Vertex* src, Vertex* dst, VertexList* mesh, Comparator& c,
mesh->remove(src);
}
+bool out_of_range_and_collinear(const SkPoint& p, Edge* edge, Comparator& c) {
+ if (c.sweep_lt(p, edge->fTop->fPoint) &&
+ !Line(p, edge->fBottom->fPoint).dist(edge->fTop->fPoint)) {
+ return true;
+ } else if (c.sweep_lt(edge->fBottom->fPoint, p) &&
+ !Line(edge->fTop->fPoint, p).dist(edge->fBottom->fPoint)) {
+ return true;
+ }
+ return false;
+}
+
Vertex* create_sorted_vertex(const SkPoint& p, uint8_t alpha, VertexList* mesh,
Vertex* reference, Comparator& c, SkArenaAlloc& alloc) {
Vertex* prevV = reference;
@@ -1163,12 +1174,6 @@ Vertex* create_sorted_vertex(const SkPoint& p, uint8_t alpha, VertexList* mesh,
return v;
}
-bool nearly_flat(Comparator& c, Edge* edge) {
- SkPoint diff = edge->fBottom->fPoint - edge->fTop->fPoint;
- float primaryDiff = c.fDirection == Comparator::Direction::kHorizontal ? diff.fX : diff.fY;
- return fabs(primaryDiff) < std::numeric_limits<float>::epsilon();
-}
-
bool check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, Vertex** current,
VertexList* mesh, Comparator& c, SkArenaAlloc& alloc) {
if (!edge || !other) {
@@ -1177,7 +1182,13 @@ bool check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, Vert
SkPoint p;
uint8_t alpha;
if (edge->intersect(*other, &p, &alpha) && p.isFinite()) {
- Vertex* v = nullptr;
+ // Ignore any out-of-range intersections which are also collinear,
+ // since the resulting edges would cancel each other out by merging.
+ if (out_of_range_and_collinear(p, edge, c) ||
+ out_of_range_and_collinear(p, other, c)) {
+ return false;
+ }
+ Vertex* v;
LOG("found intersection, pt is %g, %g\n", p.fX, p.fY);
Vertex* top = *current;
// If the intersection point is above the current vertex, rewind to the vertex above the
@@ -1185,23 +1196,15 @@ bool check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, Vert
while (top && c.sweep_lt(p, top->fPoint)) {
top = top->fPrev;
}
- if (p == edge->fTop->fPoint ||
- (c.sweep_lt(p, edge->fTop->fPoint) && !nearly_flat(c, edge))) {
+ if (p == edge->fTop->fPoint) {
v = edge->fTop;
- }
- if (p == edge->fBottom->fPoint ||
- (c.sweep_lt(edge->fBottom->fPoint, p) && !nearly_flat(c, edge))) {
+ } else if (p == edge->fBottom->fPoint) {
v = edge->fBottom;
- }
- if (p == other->fTop->fPoint ||
- (c.sweep_lt(p, other->fTop->fPoint) && !nearly_flat(c, other))) {
+ } else if (p == other->fTop->fPoint) {
v = other->fTop;
- }
- if (p == other->fBottom->fPoint ||
- (c.sweep_lt(other->fBottom->fPoint, p) && !nearly_flat(c, other))) {
+ } else if (p == other->fBottom->fPoint) {
v = other->fBottom;
- }
- if (!v) {
+ } else {
v = create_sorted_vertex(p, alpha, mesh, top, c, alloc);
if (edge->fTop->fPartner) {
Line line1 = edge->fLine;