aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrTessellator.cpp
diff options
context:
space:
mode:
authorGravatar Stephen White <senorblanco@chromium.org>2018-06-05 18:45:07 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-06 15:01:41 +0000
commite62999f6efcffb12eff9502ec3603a3ed50b6e32 (patch)
treeba7f8988a6765ae93bdc66dfe912a75e4068afba /src/gpu/GrTessellator.cpp
parente2aa7b6a554a92047b8426a7dddd0cf127fa1238 (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.cpp26
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;