diff options
author | Stephen White <senorblanco@chromium.org> | 2017-06-12 11:43:18 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-06-12 17:44:23 +0000 |
commit | e3a0be73a61147379ab0ce33a0e773c072c47908 (patch) | |
tree | a4ed24b3f8bca843a67a54621eccab36b245e68b | |
parent | 50b84682c897093d35f9ce5d351574a65d3a8219 (diff) |
GrTessellator: fix two NaN issues.
If a point in the path rounds to +inf/-inf, the intersection code can
produce NaN, which is unsortable. Fix: ignore non-finite intersections.
Quadratic interpolation can sometimes produce NaN, which will never
satisfy the flatness criterion. Abort if any of the interpolated points
are non-finite.
Bug:732023
Change-Id: If5881796e589c75b8f74459f42d00918619713a2
Reviewed-on: https://skia-review.googlesource.com/19467
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Stephen White <senorblanco@chromium.org>
-rw-r--r-- | src/gpu/GrTessellator.cpp | 5 | ||||
-rw-r--r-- | tests/TessellatingPathRendererTests.cpp | 22 |
2 files changed, 26 insertions, 1 deletions
diff --git a/src/gpu/GrTessellator.cpp b/src/gpu/GrTessellator.cpp index 1ce129dcab..5f25e5a5fb 100644 --- a/src/gpu/GrTessellator.cpp +++ b/src/gpu/GrTessellator.cpp @@ -632,6 +632,9 @@ SkScalar quad_error_at(const SkPoint pts[3], SkScalar t, SkScalar u) { SkPoint p0 = to_point(quad.eval(t - 0.5f * u)); SkPoint mid = to_point(quad.eval(t)); SkPoint p1 = to_point(quad.eval(t + 0.5f * u)); + if (!p0.isFinite() || !mid.isFinite() || !p1.isFinite()) { + return 0; + } return mid.distanceToLineSegmentBetweenSqd(p0, p1); } @@ -1082,7 +1085,7 @@ bool check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, Vert } SkPoint p; uint8_t alpha; - if (edge->intersect(*other, &p, &alpha)) { + if (edge->intersect(*other, &p, &alpha) && p.isFinite()) { Vertex* v; LOG("found intersection, pt is %g, %g\n", p.fX, p.fY); Vertex* top = *current; diff --git a/tests/TessellatingPathRendererTests.cpp b/tests/TessellatingPathRendererTests.cpp index e2fca2eb82..c41e9cf3c5 100644 --- a/tests/TessellatingPathRendererTests.cpp +++ b/tests/TessellatingPathRendererTests.cpp @@ -326,6 +326,26 @@ static SkPath create_path_20() { return path; } +// An intersection whose result is NaN (due to rounded-to-inf endpoint). +static SkPath create_path_21() { + SkPath path; + path.moveTo(1.7889142061167663539e+38, 39338463358011572224.0); + path.lineTo( 1647.4193115234375, -522.603515625); + path.lineTo( 1677.74560546875, -529.0028076171875); + path.lineTo( 1678.29541015625, -528.7847900390625); + path.lineTo( 1637.5167236328125, -519.79266357421875); + path.lineTo( 1647.4193115234375, -522.603515625); + return path; +} + +// A quad which becomes NaN when interpolated. +static SkPath create_path_22() { + SkPath path; + path.moveTo(-5.71889e+13f, 1.36759e+09f); + path.quadTo(2.45472e+19f, -3.12406e+15f, -2.19589e+18f, 2.79462e+14f); + return path; +} + static sk_sp<GrFragmentProcessor> create_linear_gradient_processor(GrContext* ctx) { SkPoint pts[2] = { {0, 0}, {1, 1} }; SkColor colors[2] = { SK_ColorGREEN, SK_ColorBLUE }; @@ -403,5 +423,7 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(TessellatingPathRendererTests, reporter, ctxInfo) { test_path(ctx, rtc.get(), create_path_18()); test_path(ctx, rtc.get(), create_path_19()); test_path(ctx, rtc.get(), create_path_20(), SkMatrix(), GrAAType::kCoverage); + test_path(ctx, rtc.get(), create_path_21(), SkMatrix(), GrAAType::kCoverage); + test_path(ctx, rtc.get(), create_path_22()); } #endif |