aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrPathUtils.cpp
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2017-06-12 11:22:54 -0600
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-06-12 17:55:45 +0000
commit390f6cd6f9f9ddd8a53da804cee3eff60cd2e2b4 (patch)
tree06393a157d4e7c2f428a3c63d0c1d6569c255d10 /src/gpu/GrPathUtils.cpp
parente3a0be73a61147379ab0ce33a0e773c072c47908 (diff)
Convert SkClassifyCubic to double precision
Even though it's in homogeneous coordinates, we still get unfortunate artifacts if this math is not done in double precision. Prioritizing correctness for now; we can revisit in the future as the need for performance dictates. Bug: skia: Change-Id: If416ef6b70291f1454fcb9f7630d1108644ac2a5 Reviewed-on: https://skia-review.googlesource.com/19501 Commit-Queue: Chris Dalton <csmartdalton@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com>
Diffstat (limited to 'src/gpu/GrPathUtils.cpp')
-rw-r--r--src/gpu/GrPathUtils.cpp38
1 files changed, 21 insertions, 17 deletions
diff --git a/src/gpu/GrPathUtils.cpp b/src/gpu/GrPathUtils.cpp
index 022d2c63ad..6047e60258 100644
--- a/src/gpu/GrPathUtils.cpp
+++ b/src/gpu/GrPathUtils.cpp
@@ -763,7 +763,7 @@ static void calc_inf_cusp_klm(const SkPoint pts[4], SkScalar tn, SkScalar sn, Sk
// | ..L.. | * | . . . . | == | 0 0 1/3 1 |
// | ..K.. | | 1 1 1 1 | | 0 1/3 2/3 1 |
//
-static void calc_quadratic_klm(const SkPoint pts[4], SkScalar d3, SkMatrix* klm) {
+static void calc_quadratic_klm(const SkPoint pts[4], double d3, SkMatrix* klm) {
SkMatrix klmAtPts;
klmAtPts.setAll(0, 1.f/3, 1,
0, 0, 1,
@@ -798,22 +798,26 @@ static void calc_line_klm(const SkPoint pts[4], SkMatrix* klm) {
-nx, -ny, k);
}
-SkCubicType GrPathUtils::getCubicKLM(const SkPoint src[4], SkMatrix* klm, SkScalar t[2],
- SkScalar s[2]) {
- SkScalar d[4];
+SkCubicType GrPathUtils::getCubicKLM(const SkPoint src[4], SkMatrix* klm, double t[2],
+ double s[2]) {
+ double d[4];
SkCubicType type = SkClassifyCubic(src, t, s, d);
+
+ const SkScalar tt[2] = {static_cast<SkScalar>(t[0]), static_cast<SkScalar>(t[1])};
+ const SkScalar ss[2] = {static_cast<SkScalar>(s[0]), static_cast<SkScalar>(s[1])};
+
switch (type) {
case SkCubicType::kSerpentine:
- calc_serp_klm(src, t[0], s[0], t[1], s[1], klm);
+ calc_serp_klm(src, tt[0], ss[0], tt[1], ss[1], klm);
break;
case SkCubicType::kLoop:
- calc_loop_klm(src, t[0], s[0], t[1], s[1], klm);
+ calc_loop_klm(src, tt[0], ss[0], tt[1], ss[1], klm);
break;
case SkCubicType::kLocalCusp:
- calc_serp_klm(src, t[0], s[0], t[1], s[1], klm);
+ calc_serp_klm(src, tt[0], ss[0], tt[1], ss[1], klm);
break;
case SkCubicType::kCuspAtInfinity:
- calc_inf_cusp_klm(src, t[0], s[0], klm);
+ calc_inf_cusp_klm(src, tt[0], ss[0], klm);
break;
case SkCubicType::kQuadratic:
calc_quadratic_klm(src, d[3], klm);
@@ -831,20 +835,20 @@ int GrPathUtils::chopCubicAtLoopIntersection(const SkPoint src[4], SkPoint dst[1
SkSTArray<2, SkScalar> chops;
*loopIndex = -1;
- SkScalar t[2], s[2];
+ double t[2], s[2];
if (SkCubicType::kLoop == GrPathUtils::getCubicKLM(src, klm, t, s)) {
- t[0] /= s[0];
- t[1] /= s[1];
- SkASSERT(t[0] <= t[1]); // Technically t0 != t1 in a loop, but there may be FP error.
+ SkScalar t0 = static_cast<SkScalar>(t[0] / s[0]);
+ SkScalar t1 = static_cast<SkScalar>(t[1] / s[1]);
+ SkASSERT(t0 <= t1); // Technically t0 != t1 in a loop, but there may be FP error.
- if (t[0] < 1 && t[1] > 0) {
+ if (t0 < 1 && t1 > 0) {
*loopIndex = 0;
- if (t[0] > 0) {
- chops.push_back(t[0]);
+ if (t0 > 0) {
+ chops.push_back(t0);
*loopIndex = 1;
}
- if (t[1] < 1) {
- chops.push_back(t[1]);
+ if (t1 < 1) {
+ chops.push_back(t1);
*loopIndex = chops.count() - 1;
}
}