aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkAnalyticEdge.cpp
diff options
context:
space:
mode:
authorGravatar Yuqian Li <liyuqian@google.com>2017-08-08 14:00:52 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-08-09 21:05:35 +0000
commit5eb8fc585e9b3c9ccc82b0921986e1020ddaff23 (patch)
tree4ebfe1a26d0bd2fc0eb7c27e3fc8581af46777ef /src/core/SkAnalyticEdge.cpp
parent0f450acd76fd58a2f7464f99869ed6afbfac303c (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.cpp24
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;
}