Fix performance issue and compute intersections more often.

(This CL also turned on Analytic AA for concave paths by removing SK_SUPPORT_LEGACY_AAA flag.)

Performance:
The SK_ALWAYS_INLINE was restored because it could bring 30%-50% speedup
in certain convex cases (e.g., fill_big_triangle). We also have to
reduce the number of branchings in the concave code path to enable such
speedup. (Although the speedup is for convex cases. The assembly code is
so strange...)

Intersection:
Previously, the criterion is too loose and that caused some bad pixels
(mostly unnoticeable by human eyes without magnifying). For example,
pixel (198, 222) of
https://gold.skia.org/detail?test=parsedpaths&digest=979e81de6f7b3f9e7e8dc810e31cad8d


BUG=skia:

Change-Id: I5e8191865c3df625f895cd4588c67c283fcbeaec
Reviewed-on: https://skia-review.googlesource.com/7318
Reviewed-by: Cary Clark <caryclark@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Yuqian Li <liyuqian@google.com>
This commit is contained in:
Yuqian Li 2017-01-19 16:29:02 -05:00 committed by Skia Commit-Bot
parent 85f58b5ac9
commit 6987b00fae
3 changed files with 7 additions and 28 deletions

View File

@ -10,11 +10,6 @@
#include "SkEdge.h" #include "SkEdge.h"
// Use this to check that we successfully guard the change against Chromium layout tests
#ifndef SK_SUPPORT_LEGACY_AAA
# define SK_SUPPORT_LEGACY_AAA
#endif
struct SkAnalyticEdge { struct SkAnalyticEdge {
// Similar to SkEdge, the conic edges will be converted to quadratic edges // Similar to SkEdge, the conic edges will be converted to quadratic edges
enum Type { enum Type {

View File

@ -23,11 +23,6 @@ class SkPath;
*/ */
typedef SkIRect SkXRect; typedef SkIRect SkXRect;
// Use this to check that we successfully guard the change against Chromium layout tests
#ifndef SK_SUPPORT_LEGACY_AAA
# define SK_SUPPORT_LEGACY_AAA
#endif
extern std::atomic<bool> gSkUseAnalyticAA; extern std::atomic<bool> gSkUseAnalyticAA;
extern std::atomic<bool> gSkForceAnalyticAA; extern std::atomic<bool> gSkForceAnalyticAA;

View File

@ -1516,20 +1516,9 @@ static void aaa_walk_edges(SkAnalyticEdge* prevHead, SkAnalyticEdge* nextTail,
} else { } else {
SkFixed rite = currE->fX; SkFixed rite = currE->fX;
currE->goY(nextY, yShift); currE->goY(nextY, yShift);
if (leftE->fDX < 0) { leftE->fX = SkTMax(leftClip, leftE->fX);
left = SkTMax(leftClip, left); rite = SkTMin(rightClip, rite);
leftE->fX = SkTMax(leftClip, leftE->fX); currE->fX = SkTMin(rightClip, currE->fX);
} else {
left = SkTMin(rightClip, left);
leftE->fX = SkTMin(rightClip, leftE->fX);
}
if (currE->fDX < 0) {
rite = SkTMax(leftClip, rite);
currE->fX = SkTMax(leftClip, currE->fX);
} else {
rite = SkTMin(rightClip, rite);
currE->fX = SkTMin(rightClip, currE->fX);
}
blit_trapezoid_row(blitter, y >> 16, left, rite, leftE->fX, currE->fX, blit_trapezoid_row(blitter, y >> 16, left, rite, leftE->fX, currE->fX,
leftDY, currE->fDY, fullAlpha, maskRow, isUsingMask, leftDY, currE->fDY, fullAlpha, maskRow, isUsingMask,
noRealBlitter || (fullAlpha == 0xFF && ( noRealBlitter || (fullAlpha == 0xFF && (
@ -1541,7 +1530,7 @@ static void aaa_walk_edges(SkAnalyticEdge* prevHead, SkAnalyticEdge* nextTail,
} }
} else { } else {
if (isLeft) { if (isLeft) {
left = currE->fX; left = SkTMax(currE->fX, leftClip);
leftDY = currE->fDY; leftDY = currE->fDY;
leftE = currE; leftE = currE;
leftEnds = leftE->fLowerY == nextY; leftEnds = leftE->fLowerY == nextY;
@ -1606,7 +1595,7 @@ static void aaa_walk_edges(SkAnalyticEdge* prevHead, SkAnalyticEdge* nextTail,
leftClip, rightClip, yShift); leftClip, rightClip, yShift);
} else { } else {
blit_trapezoid_row(blitter, y >> 16, blit_trapezoid_row(blitter, y >> 16,
SkTMax(leftClip, left), rightClip, left, rightClip,
SkTMax(leftClip, leftE->fX), rightClip, SkTMax(leftClip, leftE->fX), rightClip,
leftDY, 0, fullAlpha, maskRow, isUsingMask, leftDY, 0, fullAlpha, maskRow, isUsingMask,
noRealBlitter || noRealBlitter ||
@ -1629,7 +1618,7 @@ static void aaa_walk_edges(SkAnalyticEdge* prevHead, SkAnalyticEdge* nextTail,
} }
} }
static void aaa_fill_path(const SkPath& path, const SkIRect& clipRect, static SK_ALWAYS_INLINE void aaa_fill_path(const SkPath& path, const SkIRect& clipRect,
AdditiveBlitter* blitter, int start_y, int stop_y, bool pathContainedInClip, AdditiveBlitter* blitter, int start_y, int stop_y, bool pathContainedInClip,
bool isUsingMask, bool forceRLE) { // forceRLE implies that SkAAClip is calling us bool isUsingMask, bool forceRLE) { // forceRLE implies that SkAAClip is calling us
SkASSERT(blitter); SkASSERT(blitter);
@ -1724,7 +1713,7 @@ static void aaa_fill_path(const SkPath& path, const SkIRect& clipRect,
// We skip intersection computation if there are many points which probably already // We skip intersection computation if there are many points which probably already
// give us enough fractional scan lines. // give us enough fractional scan lines.
bool skipIntersect = path.countPoints() > (stop_y - start_y) / 2; bool skipIntersect = path.countPoints() > (stop_y - start_y) * 2;
aaa_walk_edges(&headEdge, &tailEdge, path.getFillType(), blitter, start_y, stop_y, aaa_walk_edges(&headEdge, &tailEdge, path.getFillType(), blitter, start_y, stop_y,
leftBound, rightBound, isUsingMask, forceRLE, useDeferred, skipIntersect); leftBound, rightBound, isUsingMask, forceRLE, useDeferred, skipIntersect);