diff options
author | 2016-11-14 11:51:41 -0500 | |
---|---|---|
committer | 2016-11-14 17:38:05 +0000 | |
commit | 0038b7feaaa3d2337b2e44938a11bd0f475cd525 (patch) | |
tree | c217efb2dcbc5e9e1cbaed1e8c01f19419dc1b27 | |
parent | efa62e1d5b74d3ef09c4cdddf871594aece267a1 (diff) |
Remove accumulative snapping error
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4769
Change-Id: Ie70bdc280c680c82f3b8a186466bf3a0835a9107
Reviewed-on: https://skia-review.googlesource.com/4769
Reviewed-by: Cary Clark <caryclark@google.com>
Commit-Queue: Yuqian Li <liyuqian@google.com>
-rw-r--r-- | gm/aaa.cpp | 14 | ||||
-rw-r--r-- | src/core/SkAnalyticEdge.cpp | 4 |
2 files changed, 16 insertions, 2 deletions
diff --git a/gm/aaa.cpp b/gm/aaa.cpp index 4788969de4..72f953a701 100644 --- a/gm/aaa.cpp +++ b/gm/aaa.cpp @@ -61,6 +61,20 @@ protected: path.lineTo(SkBits2Float(0x429b9d5c), SkBits2Float(0x4367a041)); // 77.8073f, 231.626f path.close(); canvas->drawPath(path, p); + + // The following path reveals a subtle SkAnalyticQuadraticEdge::updateQuadratic bug: + // we should not use any snapped y for the intermediate values whose error may accumulate; + // snapping should only be allowed once before updateLine. + path.reset(); + path.moveTo(SkBits2Float(0x434ba71e), SkBits2Float(0x438a06d0)); // 203.653f, 276.053f + path.lineTo(SkBits2Float(0x43492a74), SkBits2Float(0x4396d70d)); // 201.166f, 301.68f + // 200.921f, 304.207f, 196.939f, 303.82f, 0.707107f + path.conicTo(SkBits2Float(0x4348ebaf), SkBits2Float(0x43981a75), + SkBits2Float(0x4344f079), SkBits2Float(0x4397e900), SkBits2Float(0x3f3504f3)); + path.close(); + // Manually setting convexity is required. Otherwise, this path will be considered concave. + path.setConvexity(SkPath::kConvex_Convexity); + canvas->drawPath(path, p); } private: diff --git a/src/core/SkAnalyticEdge.cpp b/src/core/SkAnalyticEdge.cpp index 74047836fa..ee7eda7b52 100644 --- a/src/core/SkAnalyticEdge.cpp +++ b/src/core/SkAnalyticEdge.cpp @@ -135,13 +135,13 @@ bool SkAnalyticQuadraticEdge::updateQuadratic() { if (--count > 0) { newx = oldx + (dx >> shift); - newy = snapY(oldy + (dy >> shift)); + newy = oldy + (dy >> shift); slope = dy >> 10 > 0 ? quickSkFDot6Div(dx >> 10, dy >> 10) : SK_MaxS32; if (SkAbs32(dy) >= SK_Fixed1 * 2) { // only snap when dy is large enough newSnappedY = SkTMin<SkFixed>(fQEdge.fQLastY, SkFixedRoundToFixed(newy)); newSnappedX = newx + SkFixedMul_lowprec(slope, newSnappedY - newy); } else { - newSnappedY = newy; + newSnappedY = SkTMin(fQEdge.fQLastY, snapY(newy)); newSnappedX = newx; } dx += fQEdge.fQDDx; |