diff options
author | Yuqian Li <liyuqian@google.com> | 2017-01-13 10:13:13 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-01-13 16:07:48 +0000 |
commit | 550148ba572acc75e73d3c7d600ea7fa43db55f2 (patch) | |
tree | 68814ff1d5d49683928208c2d25ca64ccc18f817 /src/core/SkAnalyticEdge.h | |
parent | 905a94ff39edae7b86d060b4a13aadc838769398 (diff) |
The only difference is that we now also put the guard flag
SK_SUPPORT_LEGACY_AAA in SkUserConfig.h. Previously, SkAnalyticEdge.cpp doesn't
get that flag from SkScan.h and that caused many problems.
BUG=skia:
TBR=reed@google.com,caryclark@google.com
Change-Id: I134bb76cebd6fffa712f438076668765321bba3b
Reviewed-on: https://skia-review.googlesource.com/6992
Reviewed-by: Yuqian Li <liyuqian@google.com>
Commit-Queue: Yuqian Li <liyuqian@google.com>
Diffstat (limited to 'src/core/SkAnalyticEdge.h')
-rw-r--r-- | src/core/SkAnalyticEdge.h | 91 |
1 files changed, 67 insertions, 24 deletions
diff --git a/src/core/SkAnalyticEdge.h b/src/core/SkAnalyticEdge.h index 7f5e62c519..1ed25f39ea 100644 --- a/src/core/SkAnalyticEdge.h +++ b/src/core/SkAnalyticEdge.h @@ -10,6 +10,11 @@ #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 { // Similar to SkEdge, the conic edges will be converted to quadratic edges enum Type { @@ -21,6 +26,10 @@ struct SkAnalyticEdge { SkAnalyticEdge* fNext; SkAnalyticEdge* fPrev; + // During aaa_walk_edges, if this edge is a left edge, + // then fRiteE is its corresponding right edge. Otherwise it's nullptr. + SkAnalyticEdge* fRiteE; + SkFixed fX; SkFixed fDX; SkFixed fUpperX; // The x value when y = fUpperY @@ -30,6 +39,10 @@ struct SkAnalyticEdge { SkFixed fDY; // abs(1/fDX); may be SK_MaxS32 when fDX is close to 0. // fDY is only used for blitting trapezoids. + SkFixed fSavedX; // For deferred blitting + SkFixed fSavedY; // For deferred blitting + SkFixed fSavedDY; // For deferred blitting + int8_t fCurveCount; // only used by kQuad(+) and kCubic(-) uint8_t fCurveShift; // appled to all Dx/DDx/DDDx except for fCubicDShift exception uint8_t fCubicDShift; // applied to fCDx and fCDy only in cubic @@ -37,7 +50,8 @@ struct SkAnalyticEdge { static const int kDefaultAccuracy = 2; // default accuracy for snapping - static inline SkFixed snapY(SkFixed y, int accuracy = kDefaultAccuracy) { + static inline SkFixed SnapY(SkFixed y) { + const int accuracy = kDefaultAccuracy; // This approach is safer than left shift, round, then right shift return ((unsigned)y + (SK_Fixed1 >> (accuracy + 1))) >> (16 - accuracy) << (16 - accuracy); } @@ -55,15 +69,22 @@ struct SkAnalyticEdge { } } - inline bool setLine(const SkPoint& p0, const SkPoint& p1, const SkIRect* clip = nullptr); - inline bool updateLine(SkFixed ax, SkFixed ay, SkFixed bx, SkFixed by, SkFixed slope); - void chopLineWithClip(const SkIRect& clip); + inline void goY(SkFixed y, int yShift) { + SkASSERT(yShift >= 0 && yShift <= kDefaultAccuracy); + SkASSERT(fDX == 0 || y - fY == SK_Fixed1 >> yShift); + fY = y; + fX += fDX >> yShift; + } - inline bool intersectsClip(const SkIRect& clip) const { - SkASSERT(SkFixedFloorToInt(fUpperY) < clip.fBottom); - return SkFixedCeilToInt(fLowerY) > clip.fTop; + inline void saveXY(SkFixed x, SkFixed y, SkFixed dY) { + fSavedX = x; + fSavedY = y; + fSavedDY = dY; } + inline bool setLine(const SkPoint& p0, const SkPoint& p1); + inline bool updateLine(SkFixed ax, SkFixed ay, SkFixed bx, SkFixed by, SkFixed slope); + #ifdef SK_DEBUG void dump() const { SkDebugf("edge: upperY:%d lowerY:%d y:%g x:%g dx:%g w:%d\n", @@ -90,36 +111,47 @@ struct SkAnalyticQuadraticEdge : public SkAnalyticEdge { bool setQuadratic(const SkPoint pts[3]); bool updateQuadratic(); + inline void keepContinuous() { + // We use fX as the starting x to ensure the continuouty. + // Without it, we may break the sorted edge list. + SkASSERT(SkAbs32(fX - SkFixedMul(fY - fSnappedY, fDX) - fSnappedX) < SK_Fixed1); + SkASSERT(SkAbs32(fY - fSnappedY) < SK_Fixed1); // This may differ due to smooth jump + fSnappedX = fX; + fSnappedY = fY; + } }; struct SkAnalyticCubicEdge : public SkAnalyticEdge { SkCubicEdge fCEdge; + SkFixed fSnappedY; // to make sure that y is increasing with smooth jump and snapping + bool setCubic(const SkPoint pts[4]); bool updateCubic(); + inline void keepContinuous() { + SkASSERT(SkAbs32(fX - SkFixedMul(fDX, fY - SnapY(fCEdge.fCy)) - fCEdge.fCx) < SK_Fixed1); + fCEdge.fCx = fX; + fSnappedY = fY; + } }; -bool SkAnalyticEdge::setLine(const SkPoint& p0, const SkPoint& p1, const SkIRect* clip) { - // We must set X/Y using the same way (times 4, to FDot6, then to Fixed) as Quads/Cubics. +bool SkAnalyticEdge::setLine(const SkPoint& p0, const SkPoint& p1) { + fRiteE = nullptr; + + // We must set X/Y using the same way (e.g., times 4, to FDot6, then to Fixed) as Quads/Cubics. // Otherwise the order of the edge might be wrong due to precision limit. - SkFixed x0 = SkFDot6ToFixed(SkScalarToFDot6(p0.fX * 4)) >> 2; - SkFixed y0 = snapY(SkFDot6ToFixed(SkScalarToFDot6(p0.fY * 4)) >> 2); - SkFixed x1 = SkFDot6ToFixed(SkScalarToFDot6(p1.fX * 4)) >> 2; - SkFixed y1 = snapY(SkFDot6ToFixed(SkScalarToFDot6(p1.fY * 4)) >> 2); + const int accuracy = kDefaultAccuracy; + const int multiplier = (1 << kDefaultAccuracy); + SkFixed x0 = SkFDot6ToFixed(SkScalarToFDot6(p0.fX * multiplier)) >> accuracy; + SkFixed y0 = SnapY(SkFDot6ToFixed(SkScalarToFDot6(p0.fY * multiplier)) >> accuracy); + SkFixed x1 = SkFDot6ToFixed(SkScalarToFDot6(p1.fX * multiplier)) >> accuracy; + SkFixed y1 = SnapY(SkFDot6ToFixed(SkScalarToFDot6(p1.fY * multiplier)) >> accuracy); // are we a zero-height line? if (y0 == y1) { return false; } - int top = SkFixedFloorToInt(y0); - int bot = SkFixedCeilToInt(y1); - - // are we completely above or below the clip? - if (clip && (top >= clip->fBottom || bot <= clip->fTop)) { - return false; - } - int winding = 1; if (y0 > y1) { @@ -128,7 +160,15 @@ bool SkAnalyticEdge::setLine(const SkPoint& p0, const SkPoint& p1, const SkIRect winding = -1; } +#ifdef SK_SUPPORT_LEGACY_AAA SkFixed slope = SkFixedDiv(x1 - x0, y1 - y0); +#else + SkFDot6 dy = SkFixedToFDot6(y1 - y0); + SkFDot6 dx = SkFixedToFDot6(x1 - x0); + SkFixed slope = dy ? QuickSkFDot6Div(dx, dy) : SK_MaxS32; + SkASSERT(dx == 0 || slope != 0); + SkFixed absSlope = SkAbs32(slope); +#endif fX = x0; fDX = slope; @@ -136,14 +176,17 @@ bool SkAnalyticEdge::setLine(const SkPoint& p0, const SkPoint& p1, const SkIRect fY = y0; fUpperY = y0; fLowerY = y1; +#ifdef SK_SUPPORT_LEGACY_AAA fDY = x1 != x0 ? SkAbs32(SkFixedDiv(y1 - y0, x1 - x0)) : SK_MaxS32; +#else + fDY = dx == 0 ? SK_MaxS32 : absSlope < kInverseTableSize + ? QuickFDot6Inverse::Lookup(absSlope) + : SkAbs32(QuickSkFDot6Div(dy, dx)); +#endif fCurveCount = 0; fWinding = SkToS8(winding); fCurveShift = 0; - if (clip) { - this->chopLineWithClip(*clip); - } return true; } |