diff options
author | Stephen White <senorblanco@chromium.org> | 2018-06-05 18:45:07 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-06-06 15:01:41 +0000 |
commit | e62999f6efcffb12eff9502ec3603a3ed50b6e32 (patch) | |
tree | ba7f8988a6765ae93bdc66dfe912a75e4068afba /src/gpu/GrTessellator.cpp | |
parent | e2aa7b6a554a92047b8426a7dddd0cf127fa1238 (diff) |
GrTessellator: yet another out-of-range splitting fix.
It's actually possible for an intersection to be out-of-range on both
the intersected edges (e.g., below both bottom points), because
floating point. So we need to clamp against both edges.
Bug: 846014
Change-Id: I9fe25a1fcd3b5242af7b1ee36b17f1e968aeb836
Reviewed-on: https://skia-review.googlesource.com/132323
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Stephen White <senorblanco@chromium.org>
Diffstat (limited to 'src/gpu/GrTessellator.cpp')
-rw-r--r-- | src/gpu/GrTessellator.cpp | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/src/gpu/GrTessellator.cpp b/src/gpu/GrTessellator.cpp index 7664fc96bb..79f5765ee4 100644 --- a/src/gpu/GrTessellator.cpp +++ b/src/gpu/GrTessellator.cpp @@ -1175,6 +1175,16 @@ bool nearly_flat(Comparator& c, Edge* edge) { return fabs(primaryDiff) < std::numeric_limits<float>::epsilon(); } +SkPoint clamp(SkPoint p, SkPoint min, SkPoint max, Comparator& c) { + if (c.sweep_lt(p, min)) { + return min; + } else if (c.sweep_lt(max, p)) { + return max; + } else { + return p; + } +} + bool check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, Vertex** current, VertexList* mesh, Comparator& c, SkArenaAlloc& alloc) { if (!edge || !other) { @@ -1191,15 +1201,13 @@ bool check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, Vert while (top && c.sweep_lt(p, top->fPoint)) { top = top->fPrev; } - if (c.sweep_lt(p, edge->fTop->fPoint) && !nearly_flat(c, edge)) { - v = edge->fTop; - } else if (c.sweep_lt(edge->fBottom->fPoint, p) && !nearly_flat(c, edge)) { - v = edge->fBottom; - } else if (c.sweep_lt(p, other->fTop->fPoint) && !nearly_flat(c, other)) { - v = other->fTop; - } else if (c.sweep_lt(other->fBottom->fPoint, p) && !nearly_flat(c, other)) { - v = other->fBottom; - } else if (p == edge->fTop->fPoint) { + if (!nearly_flat(c, edge)) { + p = clamp(p, edge->fTop->fPoint, edge->fBottom->fPoint, c); + } + if (!nearly_flat(c, other)) { + p = clamp(p, other->fTop->fPoint, other->fBottom->fPoint, c); + } + if (p == edge->fTop->fPoint) { v = edge->fTop; } else if (p == edge->fBottom->fPoint) { v = edge->fBottom; |