diff options
author | Yuqian Li <liyuqian@google.com> | 2017-08-08 14:00:52 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-08-09 21:05:35 +0000 |
commit | 5eb8fc585e9b3c9ccc82b0921986e1020ddaff23 (patch) | |
tree | 4ebfe1a26d0bd2fc0eb7c27e3fc8581af46777ef /src/core/SkAnalyticEdge.cpp | |
parent | 0f450acd76fd58a2f7464f99869ed6afbfac303c (diff) |
No chop at y extrema for cubics
The new Delta AA scan converter does not need the edge to be updated
with monotonic Y so chopping at y extrema is not necessary. Removing
such chopping brings ~10% performance increase to chalkboard.svg which
has tons of small cubics (the same is true for many svgs I saw).
We didn't remove the chopping for quads because that does not bring
a significant speedup. Moreover, dropping those y extremas would make
our strokecircle animation look a little more wobbly (because we would
have fewer divisions for the quads at the top and bottom of the circle).
Bug: skia:
Change-Id: I3984d2619f9f77269ed24e8cbfa9f1429ebca4a8
Reviewed-on: https://skia-review.googlesource.com/31940
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Yuqian Li <liyuqian@google.com>
Diffstat (limited to 'src/core/SkAnalyticEdge.cpp')
-rw-r--r-- | src/core/SkAnalyticEdge.cpp | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/src/core/SkAnalyticEdge.cpp b/src/core/SkAnalyticEdge.cpp index 7cb6493f8b..e2da09023d 100644 --- a/src/core/SkAnalyticEdge.cpp +++ b/src/core/SkAnalyticEdge.cpp @@ -20,6 +20,14 @@ bool SkAnalyticEdge::updateLine(SkFixed x0, SkFixed y0, SkFixed x1, SkFixed y1, SkASSERT(fWinding == 1 || fWinding == -1); SkASSERT(fCurveCount != 0); + // We don't chop at y extrema for cubics so the y is not guaranteed to be increasing for them. + // In that case, we have to swap x/y and negate the winding. + if (y0 > y1) { + SkTSwap(x0, x1); + SkTSwap(y0, y1); + fWinding = -fWinding; + } + SkASSERT(y0 <= y1); SkFDot6 dx = SkFixedToFDot6(x1 - x0); @@ -48,10 +56,10 @@ bool SkAnalyticEdge::updateLine(SkFixed x0, SkFixed y0, SkFixed x1, SkFixed y1, return true; } -bool SkAnalyticEdge::update(SkFixed last_y) { +bool SkAnalyticEdge::update(SkFixed last_y, bool sortY) { SkASSERT(last_y >= fLowerY); // we shouldn't update edge if last_y < fLowerY if (fCurveCount < 0) { - return static_cast<SkAnalyticCubicEdge*>(this)->updateCubic(); + return static_cast<SkAnalyticCubicEdge*>(this)->updateCubic(sortY); } else if (fCurveCount > 0) { return static_cast<SkAnalyticQuadraticEdge*>(this)->updateQuadratic(); } @@ -147,10 +155,10 @@ bool SkAnalyticQuadraticEdge::updateQuadratic() { return success; } -bool SkAnalyticCubicEdge::setCubic(const SkPoint pts[4]) { +bool SkAnalyticCubicEdge::setCubic(const SkPoint pts[4], bool sortY) { fRiteE = nullptr; - if (!fCEdge.setCubicWithoutUpdate(pts, kDefaultAccuracy)) { + if (!fCEdge.setCubicWithoutUpdate(pts, kDefaultAccuracy, sortY)) { return false; } @@ -174,10 +182,10 @@ bool SkAnalyticCubicEdge::setCubic(const SkPoint pts[4]) { fSnappedY = fCEdge.fCy; - return this->updateCubic(); + return this->updateCubic(sortY); } -bool SkAnalyticCubicEdge::updateCubic() { +bool SkAnalyticCubicEdge::updateCubic(bool sortY) { int success; int count = fCurveCount; SkFixed oldx = fCEdge.fCx; @@ -205,14 +213,14 @@ bool SkAnalyticCubicEdge::updateCubic() { // we want to say SkASSERT(oldy <= newy), but our finite fixedpoint // doesn't always achieve that, so we have to explicitly pin it here. - if (newy < oldy) { + if (sortY && newy < oldy) { newy = oldy; } SkFixed newSnappedY = SnapY(newy); // we want to SkASSERT(snappedNewY <= fCEdge.fCLastY), but our finite fixedpoint // doesn't always achieve that, so we have to explicitly pin it here. - if (fCEdge.fCLastY < newSnappedY) { + if (sortY && fCEdge.fCLastY < newSnappedY) { newSnappedY = fCEdge.fCLastY; count = 0; } |