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>
diff --git a/gm/aaa.cpp b/gm/aaa.cpp
index 4788969..72f953a 100644
--- a/gm/aaa.cpp
+++ b/gm/aaa.cpp
@@ -61,6 +61,20 @@
         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 7404783..ee7eda7 100644
--- a/src/core/SkAnalyticEdge.cpp
+++ b/src/core/SkAnalyticEdge.cpp
@@ -135,13 +135,13 @@
         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;