/*
 * Copyright 2016 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkAnalyticEdge.h"
#include "SkAntiRun.h"
#include "SkAutoMalloc.h"
#include "SkBlitter.h"
#include "SkEdge.h"
#include "SkEdgeBuilder.h"
#include "SkGeometry.h"
#include "SkPath.h"
#include "SkQuadClipper.h"
#include "SkRasterClip.h"
#include "SkRegion.h"
#include "SkScan.h"
#include "SkScanPriv.h"
#include "SkTSort.h"
#include "SkTemplates.h"
#include "SkUtils.h"

///////////////////////////////////////////////////////////////////////////////

/*

The following is a high-level overview of our analytic anti-aliasing
algorithm. We consider a path as a collection of line segments, as
quadratic/cubic curves are converted to small line segments. Without loss of
generality, let's assume that the draw region is [0, W] x [0, H].

Our algorithm is based on horizontal scan lines (y = c_i) as the previous
sampling-based algorithm did. However, our algorithm uses non-equal-spaced
scan lines, while the previous method always uses equal-spaced scan lines,
such as (y = 1/2 + 0, 1/2 + 1, 1/2 + 2, ...) in the previous non-AA algorithm,
and (y = 1/8 + 1/4, 1/8 + 2/4, 1/8 + 3/4, ...) in the previous
16-supersampling AA algorithm.

Our algorithm contains scan lines y = c_i for c_i that is either:

1. an integer between [0, H]

2. the y value of a line segment endpoint

3. the y value of an intersection of two line segments

For two consecutive scan lines y = c_i, y = c_{i+1}, we analytically computes
the coverage of this horizontal strip of our path on each pixel. This can be
done very efficiently because the strip of our path now only consists of
trapezoids whose top and bottom edges are y = c_i, y = c_{i+1} (this includes
rectangles and triangles as special cases).

We now describe how the coverage of single pixel is computed against such a
trapezoid. That coverage is essentially the intersection area of a rectangle
(e.g., [0, 1] x [c_i, c_{i+1}]) and our trapezoid. However, that intersection
could be complicated, as shown in the example region A below:

+-----------\----+
|            \  C|
|             \  |
\              \ |
|\      A       \|
| \              \
|  \             |
| B \            |
+----\-----------+

However, we don't have to compute the area of A directly. Instead, we can
compute the excluded area, which are B and C, quite easily, because they're
just triangles. In fact, we can prove that an excluded region (take B as an
example) is either itself a simple trapezoid (including rectangles, triangles,
and empty regions), or its opposite (the opposite of B is A + C) is a simple
trapezoid. In any case, we can compute its area efficiently.

In summary, our algorithm has a higher quality because it generates ground-
truth coverages analytically. It is also faster because it has much fewer
unnessasary horizontal scan lines. For example, given a triangle path, the
number of scan lines in our algorithm is only about 3 + H while the
16-supersampling algorithm has about 4H scan lines.

*/

///////////////////////////////////////////////////////////////////////////////

static inline void addAlpha(SkAlpha* alpha, SkAlpha delta) {
    SkASSERT(*alpha + (int)delta <= 256);
    *alpha = SkAlphaRuns::CatchOverflow(*alpha + (int)delta);
}

static inline void safelyAddAlpha(SkAlpha* alpha, SkAlpha delta) {
    *alpha = SkTMin(0xFF, *alpha + (int)delta);
}

class AdditiveBlitter : public SkBlitter {
public:
    virtual ~AdditiveBlitter() {}

    virtual SkBlitter* getRealBlitter(bool forceRealBlitter = false) = 0;

    virtual void blitAntiH(int x, int y, const SkAlpha antialias[], int len) = 0;
    virtual void blitAntiH(int x, int y, const SkAlpha alpha) = 0;
    virtual void blitAntiH(int x, int y, int width, const SkAlpha alpha) = 0;

    void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) override {
        SkDEBUGFAIL("Please call real blitter's blitAntiH instead.");
    }

    void blitV(int x, int y, int height, SkAlpha alpha) override {
        SkDEBUGFAIL("Please call real blitter's blitV instead.");
    }

    void blitH(int x, int y, int width) override {
        SkDEBUGFAIL("Please call real blitter's blitH instead.");
    }

    void blitRect(int x, int y, int width, int height) override {
        SkDEBUGFAIL("Please call real blitter's blitRect instead.");
    }

    void blitAntiRect(int x, int y, int width, int height,
                      SkAlpha leftAlpha, SkAlpha rightAlpha) override {
        SkDEBUGFAIL("Please call real blitter's blitAntiRect instead.");
    }

    virtual int getWidth() = 0;

    // Flush the additive alpha cache if floor(y) and floor(nextY) is different
    // (i.e., we'll start working on a new pixel row).
    virtual void flush_if_y_changed(SkFixed y, SkFixed nextY) = 0;
};

// We need this mask blitter because it significantly accelerates small path filling.
class MaskAdditiveBlitter : public AdditiveBlitter {
public:
    MaskAdditiveBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip,
            bool isInverse);
    ~MaskAdditiveBlitter() {
        fRealBlitter->blitMask(fMask, fClipRect);
    }

    // Most of the time, we still consider this mask blitter as the real blitter
    // so we can accelerate blitRect and others. But sometimes we want to return
    // the absolute real blitter (e.g., when we fall back to the old code path).
    SkBlitter* getRealBlitter(bool forceRealBlitter) override {
        return forceRealBlitter ? fRealBlitter : this;
    }

    // Virtual function is slow. So don't use this. Directly add alpha to the mask instead.
    void blitAntiH(int x, int y, const SkAlpha antialias[], int len) override;

    // Allowing following methods are used to blit rectangles during aaa_walk_convex_edges
    // Since there aren't many rectangles, we can still bear the slow speed of virtual functions.
    void blitAntiH(int x, int y, const SkAlpha alpha) override;
    void blitAntiH(int x, int y, int width, const SkAlpha alpha) override;
    void blitV(int x, int y, int height, SkAlpha alpha) override;
    void blitRect(int x, int y, int width, int height) override;
    void blitAntiRect(int x, int y, int width, int height,
                      SkAlpha leftAlpha, SkAlpha rightAlpha) override;

    // The flush is only needed for RLE (RunBasedAdditiveBlitter)
    void flush_if_y_changed(SkFixed y, SkFixed nextY) override {}

    int getWidth() override { return fClipRect.width(); }

    static bool canHandleRect(const SkIRect& bounds) {
        int width = bounds.width();
        if (width > MaskAdditiveBlitter::kMAX_WIDTH) {
            return false;
        }
        int64_t rb = SkAlign4(width);
        // use 64bits to detect overflow
        int64_t storage = rb * bounds.height();

        return (width <= MaskAdditiveBlitter::kMAX_WIDTH) &&
               (storage <= MaskAdditiveBlitter::kMAX_STORAGE);
    }

    // Return a pointer where pointer[x] corresonds to the alpha of (x, y)
    inline uint8_t* getRow(int y) {
        if (y != fY) {
            fY = y;
            fRow = fMask.fImage + (y - fMask.fBounds.fTop) * fMask.fRowBytes - fMask.fBounds.fLeft;
        }
        return fRow;
    }

private:
    // so we don't try to do very wide things, where the RLE blitter would be faster
    static const int kMAX_WIDTH = 32;
    static const int kMAX_STORAGE = 1024;

    SkBlitter*  fRealBlitter;
    SkMask      fMask;
    SkIRect     fClipRect;
    // we add 2 because we can write 1 extra byte at either end due to precision error
    uint32_t    fStorage[(kMAX_STORAGE >> 2) + 2];

    uint8_t*    fRow;
    int         fY;
};

MaskAdditiveBlitter::MaskAdditiveBlitter(
        SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip, bool isInverse) {
    SkASSERT(canHandleRect(ir));
    SkASSERT(!isInverse);

    fRealBlitter = realBlitter;

    fMask.fImage    = (uint8_t*)fStorage + 1; // There's 1 extra byte at either end of fStorage
    fMask.fBounds   = ir;
    fMask.fRowBytes = ir.width();
    fMask.fFormat   = SkMask::kA8_Format;

    fY = ir.fTop - 1;
    fRow = nullptr;

    fClipRect = ir;
    if (!fClipRect.intersect(clip.getBounds())) {
        SkASSERT(0);
        fClipRect.setEmpty();
    }

    memset(fStorage, 0, fMask.fBounds.height() * fMask.fRowBytes + 2);
}

void MaskAdditiveBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], int len) {
    SkFAIL("Don't use this; directly add alphas to the mask.");
}

void MaskAdditiveBlitter::blitAntiH(int x, int y, const SkAlpha alpha) {
    SkASSERT(x >= fMask.fBounds.fLeft -1);
    addAlpha(&this->getRow(y)[x], alpha);
}

void MaskAdditiveBlitter::blitAntiH(int x, int y, int width, const SkAlpha alpha) {
    SkASSERT(x >= fMask.fBounds.fLeft -1);
    uint8_t* row = this->getRow(y);
    for (int i = 0; i < width; ++i) {
        addAlpha(&row[x + i], alpha);
    }
}

void MaskAdditiveBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
    if (alpha == 0) {
        return;
    }
    SkASSERT(x >= fMask.fBounds.fLeft -1);
    // This must be called as if this is a real blitter.
    // So we directly set alpha rather than adding it.
    uint8_t* row = this->getRow(y);
    for (int i = 0; i < height; ++i) {
        row[x] = alpha;
        row += fMask.fRowBytes;
    }
}

void MaskAdditiveBlitter::blitRect(int x, int y, int width, int height) {
    SkASSERT(x >= fMask.fBounds.fLeft -1);
    // This must be called as if this is a real blitter.
    // So we directly set alpha rather than adding it.
    uint8_t* row = this->getRow(y);
    for (int i = 0; i < height; ++i) {
        memset(row + x, 0xFF, width);
        row += fMask.fRowBytes;
    }
}

void MaskAdditiveBlitter::blitAntiRect(int x, int y, int width, int height,
        SkAlpha leftAlpha, SkAlpha rightAlpha) {
    blitV(x, y, height, leftAlpha);
    blitV(x + 1 + width, y, height, rightAlpha);
    blitRect(x + 1, y, width, height);
}

class RunBasedAdditiveBlitter : public AdditiveBlitter {
public:
    RunBasedAdditiveBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip,
            bool isInverse);
    ~RunBasedAdditiveBlitter();

    SkBlitter* getRealBlitter(bool forceRealBlitter) override;

    void blitAntiH(int x, int y, const SkAlpha antialias[], int len) override;
    void blitAntiH(int x, int y, const SkAlpha alpha) override;
    void blitAntiH(int x, int y, int width, const SkAlpha alpha) override;

    int getWidth() override;

    void flush_if_y_changed(SkFixed y, SkFixed nextY) override {
        if (SkFixedFloorToInt(y) != SkFixedFloorToInt(nextY)) {
            this->flush();
        }
    }

protected:
    SkBlitter* fRealBlitter;

    /// Current y coordinate
    int         fCurrY;
    /// Widest row of region to be blitted
    int         fWidth;
    /// Leftmost x coordinate in any row
    int         fLeft;
    /// Initial y coordinate (top of bounds).
    int         fTop;

    // The next three variables are used to track a circular buffer that
    // contains the values used in SkAlphaRuns. These variables should only
    // ever be updated in advanceRuns(), and fRuns should always point to
    // a valid SkAlphaRuns...
    int         fRunsToBuffer;
    void*       fRunsBuffer;
    int         fCurrentRun;
    SkAlphaRuns fRuns;

    int         fOffsetX;

    inline bool check(int x, int width) const {
        #ifdef SK_DEBUG
        if (x < 0 || x + width > fWidth) {
            // SkDebugf("Ignore x = %d, width = %d\n", x, width);
        }
        #endif
        return (x >= 0 && x + width <= fWidth);
    }

    // extra one to store the zero at the end
    inline int getRunsSz() const { return (fWidth + 1 + (fWidth + 2)/2) * sizeof(int16_t); }

    // This function updates the fRuns variable to point to the next buffer space
    // with adequate storage for a SkAlphaRuns. It mostly just advances fCurrentRun
    // and resets fRuns to point to an empty scanline.
    inline void advanceRuns() {
        const size_t kRunsSz = this->getRunsSz();
        fCurrentRun = (fCurrentRun + 1) % fRunsToBuffer;
        fRuns.fRuns = reinterpret_cast<int16_t*>(
            reinterpret_cast<uint8_t*>(fRunsBuffer) + fCurrentRun * kRunsSz);
        fRuns.fAlpha = reinterpret_cast<SkAlpha*>(fRuns.fRuns + fWidth + 1);
        fRuns.reset(fWidth);
    }

    // Blitting 0xFF and 0 is much faster so we snap alphas close to them
    inline SkAlpha snapAlpha(SkAlpha alpha) {
        return alpha > 247 ? 0xFF : alpha < 8 ? 0 : alpha;
    }

    inline void flush() {
        if (fCurrY >= fTop) {
            SkASSERT(fCurrentRun < fRunsToBuffer);
            for (int x = 0; fRuns.fRuns[x]; x += fRuns.fRuns[x]) {
                // It seems that blitting 255 or 0 is much faster than blitting 254 or 1
                fRuns.fAlpha[x] = snapAlpha(fRuns.fAlpha[x]);
            }
            if (!fRuns.empty()) {
                // SkDEBUGCODE(fRuns.dump();)
                fRealBlitter->blitAntiH(fLeft, fCurrY, fRuns.fAlpha, fRuns.fRuns);
                this->advanceRuns();
                fOffsetX = 0;
            }
            fCurrY = fTop - 1;
        }
    }

    inline void checkY(int y) {
        if (y != fCurrY) {
            this->flush();
            fCurrY = y;
        }
    }
};

RunBasedAdditiveBlitter::RunBasedAdditiveBlitter(
        SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip, bool isInverse) {
    fRealBlitter = realBlitter;

    SkIRect sectBounds;
    if (isInverse) {
        // We use the clip bounds instead of the ir, since we may be asked to
        //draw outside of the rect when we're a inverse filltype
        sectBounds = clip.getBounds();
    } else {
        if (!sectBounds.intersect(ir, clip.getBounds())) {
            sectBounds.setEmpty();
        }
    }

    const int left = sectBounds.left();
    const int right = sectBounds.right();

    fLeft = left;
    fWidth = right - left;
    fTop = sectBounds.top();
    fCurrY = fTop - 1;

    fRunsToBuffer = realBlitter->requestRowsPreserved();
    fRunsBuffer = realBlitter->allocBlitMemory(fRunsToBuffer * this->getRunsSz());
    fCurrentRun = -1;

    this->advanceRuns();

    fOffsetX = 0;
}

RunBasedAdditiveBlitter::~RunBasedAdditiveBlitter() {
    this->flush();
}

SkBlitter* RunBasedAdditiveBlitter::getRealBlitter(bool forceRealBlitter) {
    return fRealBlitter;
}

void RunBasedAdditiveBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], int len) {
    checkY(y);
    x -= fLeft;

    if (x < 0) {
        len += x;
        antialias -= x;
        x = 0;
    }
    len = SkTMin(len, fWidth - x);
    SkASSERT(check(x, len));

    if (x < fOffsetX) {
        fOffsetX = 0;
    }

    fOffsetX = fRuns.add(x, 0, len, 0, 0, fOffsetX); // Break the run
    for (int i = 0; i < len; i += fRuns.fRuns[x + i]) {
        for (int j = 1; j < fRuns.fRuns[x + i]; j++) {
            fRuns.fRuns[x + i + j] = 1;
            fRuns.fAlpha[x + i + j] = fRuns.fAlpha[x + i];
        }
        fRuns.fRuns[x + i] = 1;
    }
    for (int i = 0; i < len; ++i) {
        addAlpha(&fRuns.fAlpha[x + i], antialias[i]);
    }
}
void RunBasedAdditiveBlitter::blitAntiH(int x, int y, const SkAlpha alpha) {
    checkY(y);
    x -= fLeft;

    if (x < fOffsetX) {
        fOffsetX = 0;
    }

    if (this->check(x, 1)) {
        fOffsetX = fRuns.add(x, 0, 1, 0, alpha, fOffsetX);
    }
}

void RunBasedAdditiveBlitter::blitAntiH(int x, int y, int width, const SkAlpha alpha) {
    checkY(y);
    x -= fLeft;

    if (x < fOffsetX) {
        fOffsetX = 0;
    }

    if (this->check(x, width)) {
        fOffsetX = fRuns.add(x, 0, width, 0, alpha, fOffsetX);
    }
}

int RunBasedAdditiveBlitter::getWidth() { return fWidth; }

// This exists specifically for concave path filling.
// In those cases, we can easily accumulate alpha greater than 0xFF.
class SafeRLEAdditiveBlitter : public RunBasedAdditiveBlitter {
public:
    SafeRLEAdditiveBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip,
            bool isInverse) : RunBasedAdditiveBlitter(realBlitter, ir, clip, isInverse) {}

    void blitAntiH(int x, int y, const SkAlpha antialias[], int len) override;
    void blitAntiH(int x, int y, const SkAlpha alpha) override;
    void blitAntiH(int x, int y, int width, const SkAlpha alpha) override;
};

void SafeRLEAdditiveBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], int len) {
    checkY(y);
    x -= fLeft;

    if (x < 0) {
        len += x;
        antialias -= x;
        x = 0;
    }
    len = SkTMin(len, fWidth - x);
    SkASSERT(check(x, len));

    if (x < fOffsetX) {
        fOffsetX = 0;
    }

    fOffsetX = fRuns.add(x, 0, len, 0, 0, fOffsetX); // Break the run
    for (int i = 0; i < len; i += fRuns.fRuns[x + i]) {
        for (int j = 1; j < fRuns.fRuns[x + i]; j++) {
            fRuns.fRuns[x + i + j] = 1;
            fRuns.fAlpha[x + i + j] = fRuns.fAlpha[x + i];
        }
        fRuns.fRuns[x + i] = 1;
    }
    for (int i = 0; i < len; ++i) {
        safelyAddAlpha(&fRuns.fAlpha[x + i], antialias[i]);
    }
}

void SafeRLEAdditiveBlitter::blitAntiH(int x, int y, const SkAlpha alpha) {
    checkY(y);
    x -= fLeft;

    if (x < fOffsetX) {
        fOffsetX = 0;
    }

    if (check(x, 1)) {
        // Break the run
        fOffsetX = fRuns.add(x, 0, 1, 0, 0, fOffsetX);
        safelyAddAlpha(&fRuns.fAlpha[x], alpha);
    }
}

void SafeRLEAdditiveBlitter::blitAntiH(int x, int y, int width, const SkAlpha alpha) {
    checkY(y);
    x -= fLeft;

    if (x < fOffsetX) {
        fOffsetX = 0;
    }

    if (check(x, width)) {
        // Break the run
        fOffsetX = fRuns.add(x, 0, width, 0, 0, fOffsetX);
        for(int i = x; i < x + width; i += fRuns.fRuns[i]) {
            safelyAddAlpha(&fRuns.fAlpha[i], alpha);
        }
    }
}

///////////////////////////////////////////////////////////////////////////////

// Return the alpha of a trapezoid whose height is 1
static inline SkAlpha trapezoidToAlpha(SkFixed l1, SkFixed l2) {
    SkASSERT(l1 >= 0 && l2 >= 0);
    return (l1 + l2) >> 9;
}

// The alpha of right-triangle (a, a*b), in 16 bits
static inline SkFixed partialTriangleToAlpha16(SkFixed a, SkFixed b) {
    SkASSERT(a <= SK_Fixed1);
    // SkFixedMul(SkFixedMul(a, a), b) >> 1
    // return ((((a >> 8) * (a >> 8)) >> 8) * (b >> 8)) >> 1;
    return (a >> 11) * (a >> 11) * (b >> 11);
}

// The alpha of right-triangle (a, a*b)
static inline SkAlpha partialTriangleToAlpha(SkFixed a, SkFixed b) {
    return partialTriangleToAlpha16(a, b) >> 8;
}

static inline SkAlpha getPartialAlpha(SkAlpha alpha, SkFixed partialHeight) {
    return SkToU8(SkFixedRoundToInt(alpha * partialHeight));
}

static inline SkAlpha getPartialAlpha(SkAlpha alpha, SkAlpha fullAlpha) {
    return ((uint16_t)alpha * fullAlpha) >> 8;
}

// For SkFixed that's close to SK_Fixed1, we can't convert it to alpha by just shifting right.
// For example, when f = SK_Fixed1, right shifting 8 will get 256, but we need 255.
// This is rarely the problem so we'll only use this for blitting rectangles.
static inline SkAlpha f2a(SkFixed f) {
    SkASSERT(f <= SK_Fixed1);
    return getPartialAlpha(0xFF, f);
}

// Suppose that line (l1, y)-(r1, y+1) intersects with (l2, y)-(r2, y+1),
// approximate (very coarsely) the x coordinate of the intersection.
static inline SkFixed approximateIntersection(SkFixed l1, SkFixed r1, SkFixed l2, SkFixed r2) {
    if (l1 > r1) { SkTSwap(l1, r1); }
    if (l2 > r2) { SkTSwap(l2, r2); }
    return (SkTMax(l1, l2) + SkTMin(r1, r2)) >> 1;
}

// Here we always send in l < SK_Fixed1, and the first alpha we want to compute is alphas[0]
static inline void computeAlphaAboveLine(SkAlpha* alphas, SkFixed l, SkFixed r,
                                         SkFixed dY, SkAlpha fullAlpha) {
    SkASSERT(l <= r);
    SkASSERT(l >> 16 == 0);
    int R = SkFixedCeilToInt(r);
    if (R == 0) {
        return;
    } else if (R == 1) {
        alphas[0] = getPartialAlpha(((R << 17) - l - r) >> 9, fullAlpha);
    } else {
        SkFixed first = SK_Fixed1 - l; // horizontal edge length of the left-most triangle
        SkFixed last = r - ((R - 1) << 16); // horizontal edge length of the right-most triangle
        SkFixed firstH = SkFixedMul(first, dY); // vertical edge of the left-most triangle
        alphas[0] = SkFixedMul(first, firstH) >> 9; // triangle alpha
        SkFixed alpha16 = firstH + (dY >> 1); // rectangle plus triangle
        for (int i = 1; i < R - 1; ++i) {
            alphas[i] = alpha16 >> 8;
            alpha16 += dY;
        }
        alphas[R - 1] = fullAlpha - partialTriangleToAlpha(last, dY);
    }
}

// Here we always send in l < SK_Fixed1, and the first alpha we want to compute is alphas[0]
static inline void computeAlphaBelowLine(
        SkAlpha* alphas, SkFixed l, SkFixed r, SkFixed dY, SkAlpha fullAlpha) {
    SkASSERT(l <= r);
    SkASSERT(l >> 16 == 0);
    int R = SkFixedCeilToInt(r);
    if (R == 0) {
        return;
    } else if (R == 1) {
        alphas[0] = getPartialAlpha(trapezoidToAlpha(l, r), fullAlpha);
    } else {
        SkFixed first = SK_Fixed1 - l; // horizontal edge length of the left-most triangle
        SkFixed last = r - ((R - 1) << 16); // horizontal edge length of the right-most triangle
        SkFixed lastH = SkFixedMul(last, dY); // vertical edge of the right-most triangle
        alphas[R-1] = SkFixedMul(last, lastH) >> 9; // triangle alpha
        SkFixed alpha16 = lastH + (dY >> 1); // rectangle plus triangle
        for (int i = R - 2; i > 0; i--) {
            alphas[i] = alpha16 >> 8;
            alpha16 += dY;
        }
        alphas[0] = fullAlpha - partialTriangleToAlpha(first, dY);
    }
}

// Note that if fullAlpha != 0xFF, we'll multiply alpha by fullAlpha
static SK_ALWAYS_INLINE void blit_single_alpha(AdditiveBlitter* blitter, int y, int x,
                              SkAlpha alpha, SkAlpha fullAlpha, SkAlpha* maskRow,
                              bool isUsingMask, bool noRealBlitter, bool needSafeCheck) {
    if (isUsingMask) {
        if (fullAlpha == 0xFF && !noRealBlitter) { // noRealBlitter is needed for concave paths
            maskRow[x] = alpha;
        } else if (needSafeCheck) {
            safelyAddAlpha(&maskRow[x], getPartialAlpha(alpha, fullAlpha));
        } else {
            addAlpha(&maskRow[x], getPartialAlpha(alpha, fullAlpha));
        }
    } else {
        if (fullAlpha == 0xFF && !noRealBlitter) {
            blitter->getRealBlitter()->blitV(x, y, 1, alpha);
        } else {
            blitter->blitAntiH(x, y, getPartialAlpha(alpha, fullAlpha));
        }
    }
}

static SK_ALWAYS_INLINE void blit_two_alphas(AdditiveBlitter* blitter, int y, int x,
                            SkAlpha a1, SkAlpha a2, SkAlpha fullAlpha, SkAlpha* maskRow,
                            bool isUsingMask, bool noRealBlitter, bool needSafeCheck) {
    if (isUsingMask) {
        if (needSafeCheck) {
            safelyAddAlpha(&maskRow[x], a1);
            safelyAddAlpha(&maskRow[x + 1], a2);
        } else {
            addAlpha(&maskRow[x], a1);
            addAlpha(&maskRow[x + 1], a2);
        }
    } else {
        if (fullAlpha == 0xFF && !noRealBlitter) {
            blitter->getRealBlitter()->blitAntiH2(x, y, a1, a2);
        } else {
            blitter->blitAntiH(x, y, a1);
            blitter->blitAntiH(x + 1, y, a2);
        }
    }
}

// It's important that this is inline. Otherwise it'll be much slower.
static SK_ALWAYS_INLINE void blit_full_alpha(AdditiveBlitter* blitter, int y, int x, int len,
                            SkAlpha fullAlpha, SkAlpha* maskRow, bool isUsingMask,
                            bool noRealBlitter, bool needSafeCheck) {
    if (isUsingMask) {
        for (int i = 0; i < len; ++i) {
            if (needSafeCheck) {
                safelyAddAlpha(&maskRow[x + i], fullAlpha);
            } else {
                addAlpha(&maskRow[x + i], fullAlpha);
            }
        }
    } else {
        if (fullAlpha == 0xFF && !noRealBlitter) {
            blitter->getRealBlitter()->blitH(x, y, len);
        } else {
            blitter->blitAntiH(x, y, len, fullAlpha);
        }
    }
}

static void blit_aaa_trapezoid_row(AdditiveBlitter* blitter, int y,
                                   SkFixed ul, SkFixed ur, SkFixed ll, SkFixed lr,
                                   SkFixed lDY, SkFixed rDY, SkAlpha fullAlpha, SkAlpha* maskRow,
                                   bool isUsingMask, bool noRealBlitter, bool needSafeCheck) {
    int L = SkFixedFloorToInt(ul), R = SkFixedCeilToInt(lr);
    int len = R - L;

    if (len == 1) {
        SkAlpha alpha = trapezoidToAlpha(ur - ul, lr - ll);
        blit_single_alpha(blitter, y, L, alpha, fullAlpha, maskRow, isUsingMask, noRealBlitter,
                needSafeCheck);
        return;
    }

    // SkDebugf("y = %d, len = %d, ul = %f, ur = %f, ll = %f, lr = %f\n", y, len,
    //         SkFixedToFloat(ul), SkFixedToFloat(ur), SkFixedToFloat(ll), SkFixedToFloat(lr));

    const int kQuickLen = 31;
    // This is faster than SkAutoSMalloc<1024>
    char quickMemory[(sizeof(SkAlpha) * 2 + sizeof(int16_t)) * (kQuickLen + 1)];
    SkAlpha* alphas;

    if (len <= kQuickLen) {
        alphas = (SkAlpha*)quickMemory;
    } else {
        alphas = new SkAlpha[(len + 1) * (sizeof(SkAlpha) * 2 + sizeof(int16_t))];
    }

    SkAlpha* tempAlphas = alphas + len + 1;
    int16_t* runs = (int16_t*)(alphas + (len + 1) * 2);

    for (int i = 0; i < len; ++i) {
        runs[i] = 1;
        alphas[i] = fullAlpha;
    }
    runs[len] = 0;

    int uL = SkFixedFloorToInt(ul);
    int lL = SkFixedCeilToInt(ll);
    if (uL + 2 == lL) { // We only need to compute two triangles, accelerate this special case
        SkFixed first = SkIntToFixed(uL) + SK_Fixed1 - ul;
        SkFixed second = ll - ul - first;
        SkAlpha a1 = fullAlpha - partialTriangleToAlpha(first, lDY);
        SkAlpha a2 = partialTriangleToAlpha(second, lDY);
        alphas[0] = alphas[0] > a1 ? alphas[0] - a1 : 0;
        alphas[1] = alphas[1] > a2 ? alphas[1] - a2 : 0;
    } else {
        computeAlphaBelowLine(tempAlphas + uL - L, ul - SkIntToFixed(uL), ll - SkIntToFixed(uL),
                lDY, fullAlpha);
        for (int i = uL; i < lL; ++i) {
            if (alphas[i - L] > tempAlphas[i - L]) {
                alphas[i - L] -= tempAlphas[i - L];
            } else {
                alphas[i - L] = 0;
            }
        }
    }

    int uR = SkFixedFloorToInt(ur);
    int lR = SkFixedCeilToInt(lr);
    if (uR + 2 == lR) { // We only need to compute two triangles, accelerate this special case
        SkFixed first = SkIntToFixed(uR) + SK_Fixed1 - ur;
        SkFixed second = lr - ur - first;
        SkAlpha a1 = partialTriangleToAlpha(first, rDY);
        SkAlpha a2 = fullAlpha - partialTriangleToAlpha(second, rDY);
        alphas[len-2] = alphas[len-2] > a1 ? alphas[len-2] - a1 : 0;
        alphas[len-1] = alphas[len-1] > a2 ? alphas[len-1] - a2 : 0;
    } else {
        computeAlphaAboveLine(tempAlphas + uR - L, ur - SkIntToFixed(uR), lr - SkIntToFixed(uR),
                rDY, fullAlpha);
        for (int i = uR; i < lR; ++i) {
            if (alphas[i - L] > tempAlphas[i - L]) {
                alphas[i - L] -= tempAlphas[i - L];
            } else {
                alphas[i - L] = 0;
            }
        }
    }

    if (isUsingMask) {
        for (int i = 0; i < len; ++i) {
            if (needSafeCheck) {
                safelyAddAlpha(&maskRow[L + i], alphas[i]);
            } else {
                addAlpha(&maskRow[L + i], alphas[i]);
            }
        }
    } else {
        if (fullAlpha == 0xFF && !noRealBlitter) {
            // Real blitter is faster than RunBasedAdditiveBlitter
            blitter->getRealBlitter()->blitAntiH(L, y, alphas, runs);
        } else {
            blitter->blitAntiH(L, y, alphas, len);
        }
    }

    if (len > kQuickLen) {
        delete [] alphas;
    }
}

static SK_ALWAYS_INLINE void blit_trapezoid_row(AdditiveBlitter* blitter, int y,
                               SkFixed ul, SkFixed ur, SkFixed ll, SkFixed lr,
                               SkFixed lDY, SkFixed rDY, SkAlpha fullAlpha,
                               SkAlpha* maskRow, bool isUsingMask, bool noRealBlitter = false,
                               bool needSafeCheck = false) {
    SkASSERT(lDY >= 0 && rDY >= 0); // We should only send in the absolte value

    if (ul > ur) {
#ifdef SK_DEBUG
        // SkDebugf("ul = %f > ur = %f!\n", SkFixedToFloat(ul), SkFixedToFloat(ur));
#endif
        return;
    }

    // Edge crosses. Approximate it. This should only happend due to precision limit,
    // so the approximation could be very coarse.
    if (ll > lr) {
#ifdef SK_DEBUG
        // SkDebugf("approximate intersection: %d %f %f\n", y,
        //          SkFixedToFloat(ll), SkFixedToFloat(lr));
#endif
        ll = lr = approximateIntersection(ul, ll, ur, lr);
    }

    if (ul == ur && ll == lr) {
        return; // empty trapzoid
    }

    // We're going to use the left line ul-ll and the rite line ur-lr
    // to exclude the area that's not covered by the path.
    // Swapping (ul, ll) or (ur, lr) won't affect that exclusion
    // so we'll do that for simplicity.
    if (ul > ll) { SkTSwap(ul, ll); }
    if (ur > lr) { SkTSwap(ur, lr); }

    SkFixed joinLeft = SkFixedCeilToFixed(ll);
    SkFixed joinRite = SkFixedFloorToFixed(ur);
    if (joinLeft <= joinRite) { // There's a rect from joinLeft to joinRite that we can blit
        if (ul < joinLeft) {
            int len = SkFixedCeilToInt(joinLeft - ul);
            if (len == 1) {
                SkAlpha alpha = trapezoidToAlpha(joinLeft - ul, joinLeft - ll);
                blit_single_alpha(blitter, y, ul >> 16, alpha, fullAlpha, maskRow, isUsingMask,
                        noRealBlitter, needSafeCheck);
            } else if (len == 2) {
                SkFixed first = joinLeft - SK_Fixed1 - ul;
                SkFixed second = ll - ul - first;
                SkAlpha a1 = partialTriangleToAlpha(first, lDY);
                SkAlpha a2 = fullAlpha - partialTriangleToAlpha(second, lDY);
                blit_two_alphas(blitter, y, ul >> 16, a1, a2, fullAlpha, maskRow, isUsingMask,
                        noRealBlitter, needSafeCheck);
            } else {
                blit_aaa_trapezoid_row(blitter, y, ul, joinLeft, ll, joinLeft, lDY, SK_MaxS32,
                                       fullAlpha, maskRow, isUsingMask, noRealBlitter,
                                       needSafeCheck);
            }
        }
        // SkAAClip requires that we blit from left to right.
        // Hence we must blit [ul, joinLeft] before blitting [joinLeft, joinRite]
        if (joinLeft < joinRite) {
            blit_full_alpha(blitter, y, SkFixedFloorToInt(joinLeft),
                            SkFixedFloorToInt(joinRite - joinLeft),
                            fullAlpha, maskRow, isUsingMask, noRealBlitter, needSafeCheck);
        }
        if (lr > joinRite) {
            int len = SkFixedCeilToInt(lr - joinRite);
            if (len == 1) {
                SkAlpha alpha = trapezoidToAlpha(ur - joinRite, lr - joinRite);
                blit_single_alpha(blitter, y, joinRite >> 16, alpha, fullAlpha, maskRow,
                                  isUsingMask, noRealBlitter, needSafeCheck);
            } else if (len == 2) {
                SkFixed first = joinRite + SK_Fixed1 - ur;
                SkFixed second = lr - ur - first;
                SkAlpha a1 = fullAlpha - partialTriangleToAlpha(first, rDY);
                SkAlpha a2 = partialTriangleToAlpha(second, rDY);
                blit_two_alphas(blitter, y, joinRite >> 16, a1, a2, fullAlpha, maskRow,
                                isUsingMask, noRealBlitter, needSafeCheck);
            } else {
                blit_aaa_trapezoid_row(blitter, y, joinRite, ur, joinRite, lr, SK_MaxS32, rDY,
                                       fullAlpha, maskRow, isUsingMask, noRealBlitter,
                                       needSafeCheck);
            }
        }
    } else {
        blit_aaa_trapezoid_row(blitter, y, ul, ur, ll, lr, lDY, rDY, fullAlpha, maskRow,
                               isUsingMask, noRealBlitter, needSafeCheck);
    }
}

///////////////////////////////////////////////////////////////////////////////

static bool operator<(const SkAnalyticEdge& a, const SkAnalyticEdge& b) {
    int valuea = a.fUpperY;
    int valueb = b.fUpperY;

    if (valuea == valueb) {
        valuea = a.fX;
        valueb = b.fX;
    }

    if (valuea == valueb) {
        valuea = a.fDX;
        valueb = b.fDX;
    }

    return valuea < valueb;
}

static SkAnalyticEdge* sort_edges(SkAnalyticEdge* list[], int count, SkAnalyticEdge** last) {
    SkTQSort(list, list + count - 1);

    // now make the edges linked in sorted order
    for (int i = 1; i < count; ++i) {
        list[i - 1]->fNext = list[i];
        list[i]->fPrev = list[i - 1];
    }

    *last = list[count - 1];
    return list[0];
}

#ifdef SK_DEBUG
    static void validate_sort(const SkAnalyticEdge* edge) {
        SkFixed y = SkIntToFixed(-32768);

        while (edge->fUpperY != SK_MaxS32) {
            edge->validate();
            SkASSERT(y <= edge->fUpperY);

            y = edge->fUpperY;
            edge = (SkAnalyticEdge*)edge->fNext;
        }
    }
#else
    #define validate_sort(edge)
#endif

// return true if we're done with this edge
static bool update_edge(SkAnalyticEdge* edge, SkFixed last_y) {
    if (last_y >= edge->fLowerY) {
        if (edge->fCurveCount < 0) {
            if (static_cast<SkAnalyticCubicEdge*>(edge)->updateCubic()) {
                return false;
            }
        } else if (edge->fCurveCount > 0) {
            if (static_cast<SkAnalyticQuadraticEdge*>(edge)->updateQuadratic()) {
                return false;
            }
        }
        return true;
    }
    SkASSERT(false);
    return false;
}

// For an edge, we consider it smooth if the Dx doesn't change much, and Dy is large enough
// For curves that are updating, the Dx is not changing much if fQDx/fCDx and fQDy/fCDy are
// relatively large compared to fQDDx/QCDDx and fQDDy/fCDDy
static inline bool isSmoothEnough(SkAnalyticEdge* thisEdge, SkAnalyticEdge* nextEdge, int stop_y) {
    if (thisEdge->fCurveCount < 0) {
        const SkCubicEdge& cEdge = static_cast<SkAnalyticCubicEdge*>(thisEdge)->fCEdge;
        int ddshift = cEdge.fCurveShift;
        return SkAbs32(cEdge.fCDx) >> 1 >= SkAbs32(cEdge.fCDDx) >> ddshift &&
                SkAbs32(cEdge.fCDy) >> 1 >= SkAbs32(cEdge.fCDDy) >> ddshift &&
                // current Dy is (fCDy - (fCDDy >> ddshift)) >> dshift
                (cEdge.fCDy - (cEdge.fCDDy >> ddshift)) >> cEdge.fCubicDShift >= SK_Fixed1;
    } else if (thisEdge->fCurveCount > 0) {
        const SkQuadraticEdge& qEdge = static_cast<SkAnalyticQuadraticEdge*>(thisEdge)->fQEdge;
        return SkAbs32(qEdge.fQDx) >> 1 >= SkAbs32(qEdge.fQDDx) &&
                SkAbs32(qEdge.fQDy) >> 1 >= SkAbs32(qEdge.fQDDy) &&
                // current Dy is (fQDy - fQDDy) >> shift
                (qEdge.fQDy - qEdge.fQDDy) >> qEdge.fCurveShift
                >= SK_Fixed1;
    }
    return SkAbs32(nextEdge->fDX - thisEdge->fDX) <= SK_Fixed1 && // DDx should be small
            nextEdge->fLowerY - nextEdge->fUpperY >= SK_Fixed1; // Dy should be large
}

// Check if the leftE and riteE are changing smoothly in terms of fDX.
// If yes, we can later skip the fractional y and directly jump to integer y.
static inline bool isSmoothEnough(SkAnalyticEdge* leftE, SkAnalyticEdge* riteE,
                           SkAnalyticEdge* currE, int stop_y) {
    if (currE->fUpperY >= stop_y << 16) {
        return false; // We're at the end so we won't skip anything
    }
    if (leftE->fLowerY + SK_Fixed1 < riteE->fLowerY) {
        return isSmoothEnough(leftE, currE, stop_y); // Only leftE is changing
    } else if (leftE->fLowerY > riteE->fLowerY + SK_Fixed1) {
        return isSmoothEnough(riteE, currE, stop_y); // Only riteE is changing
    }

    // Now both edges are changing, find the second next edge
    SkAnalyticEdge* nextCurrE = currE->fNext;
    if (nextCurrE->fUpperY >= stop_y << 16) { // Check if we're at the end
        return false;
    }
    if (*nextCurrE < *currE) {
        SkTSwap(currE, nextCurrE);
    }
    return isSmoothEnough(leftE, currE, stop_y) && isSmoothEnough(riteE, nextCurrE, stop_y);
}

static inline void aaa_walk_convex_edges(SkAnalyticEdge* prevHead,
        AdditiveBlitter* blitter, int start_y, int stop_y, SkFixed leftBound, SkFixed riteBound,
        bool isUsingMask) {
    validate_sort((SkAnalyticEdge*)prevHead->fNext);

    SkAnalyticEdge* leftE = (SkAnalyticEdge*) prevHead->fNext;
    SkAnalyticEdge* riteE = (SkAnalyticEdge*) leftE->fNext;
    SkAnalyticEdge* currE = (SkAnalyticEdge*) riteE->fNext;

    SkFixed y = SkTMax(leftE->fUpperY, riteE->fUpperY);

    #ifdef SK_DEBUG
    int frac_y_cnt = 0;
    int total_y_cnt = 0;
    #endif

    for (;;) {
        // We have to check fLowerY first because some edges might be alone (e.g., there's only
        // a left edge but no right edge in a given y scan line) due to precision limit.
        while (leftE->fLowerY <= y) { // Due to smooth jump, we may pass multiple short edges
            if (update_edge(leftE, y)) {
                if (SkFixedFloorToInt(currE->fUpperY) >= stop_y) {
                    goto END_WALK;
                }
                leftE = currE;
                currE = (SkAnalyticEdge*)currE->fNext;
            }
        }
        while (riteE->fLowerY <= y) { // Due to smooth jump, we may pass multiple short edges
            if (update_edge(riteE, y)) {
                if (SkFixedFloorToInt(currE->fUpperY) >= stop_y) {
                    goto END_WALK;
                }
                riteE = currE;
                currE = (SkAnalyticEdge*)currE->fNext;
            }
        }

        SkASSERT(leftE);
        SkASSERT(riteE);

        // check our bottom clip
        if (SkFixedFloorToInt(y) >= stop_y) {
            break;
        }

        SkASSERT(SkFixedFloorToInt(leftE->fUpperY) <= stop_y);
        SkASSERT(SkFixedFloorToInt(riteE->fUpperY) <= stop_y);

        leftE->goY(y);
        riteE->goY(y);

        if (leftE->fX > riteE->fX || (leftE->fX == riteE->fX &&
                                      leftE->fDX > riteE->fDX)) {
            SkTSwap(leftE, riteE);
        }

        SkFixed local_bot_fixed = SkMin32(leftE->fLowerY, riteE->fLowerY);
        if (isSmoothEnough(leftE, riteE, currE, stop_y)) {
            local_bot_fixed = SkFixedCeilToFixed(local_bot_fixed);
        }
        local_bot_fixed = SkMin32(local_bot_fixed, SkIntToFixed(stop_y));

        SkFixed left = SkTMax(leftBound, leftE->fX);
        SkFixed dLeft = leftE->fDX;
        SkFixed rite = SkTMin(riteBound, riteE->fX);
        SkFixed dRite = riteE->fDX;
        if (0 == (dLeft | dRite)) {
            int     fullLeft    = SkFixedCeilToInt(left);
            int     fullRite    = SkFixedFloorToInt(rite);
            SkFixed partialLeft = SkIntToFixed(fullLeft) - left;
            SkFixed partialRite = rite - SkIntToFixed(fullRite);
            int     fullTop     = SkFixedCeilToInt(y);
            int     fullBot     = SkFixedFloorToInt(local_bot_fixed);
            SkFixed partialTop  = SkIntToFixed(fullTop) - y;
            SkFixed partialBot  = local_bot_fixed - SkIntToFixed(fullBot);
            if (fullTop > fullBot) { // The rectangle is within one pixel height...
                partialTop -= (SK_Fixed1 - partialBot);
                partialBot = 0;
            }

            if (fullRite >= fullLeft) {
                if (partialTop > 0) { // blit first partial row
                    if (partialLeft > 0) {
                        blitter->blitAntiH(fullLeft - 1, fullTop - 1,
                                f2a(SkFixedMul(partialTop, partialLeft)));
                    }
                    blitter->blitAntiH(fullLeft, fullTop - 1, fullRite - fullLeft,
                                       f2a(partialTop));
                    if (partialRite > 0) {
                        blitter->blitAntiH(fullRite, fullTop - 1,
                                f2a(SkFixedMul(partialTop, partialRite)));
                    }
                    blitter->flush_if_y_changed(y, y + partialTop);
                }

                // Blit all full-height rows from fullTop to fullBot
                if (fullBot > fullTop &&
                        // SkAAClip cannot handle the empty rect so check the non-emptiness here
                        // (bug chromium:662800)
                        (fullRite > fullLeft || f2a(partialLeft) > 0 || f2a(partialRite) > 0)) {
                    blitter->getRealBlitter()->blitAntiRect(fullLeft - 1, fullTop,
                                                            fullRite - fullLeft, fullBot - fullTop,
                                                            f2a(partialLeft), f2a(partialRite));
                }

                if (partialBot > 0) { // blit last partial row
                    if (partialLeft > 0) {
                        blitter->blitAntiH(fullLeft - 1, fullBot,
                                           f2a(SkFixedMul(partialBot, partialLeft)));
                    }
                    blitter->blitAntiH(fullLeft, fullBot, fullRite - fullLeft, f2a(partialBot));
                    if (partialRite > 0) {
                        blitter->blitAntiH(fullRite, fullBot,
                                           f2a(SkFixedMul(partialBot, partialRite)));
                    }
                }
            } else { // left and rite are within the same pixel
                if (partialTop > 0) {
                    blitter->blitAntiH(fullLeft - 1, fullTop - 1, 1,
                            f2a(SkFixedMul(partialTop, rite - left)));
                    blitter->flush_if_y_changed(y, y + partialTop);
                }
                if (fullBot > fullTop) {
                    blitter->getRealBlitter()->blitV(fullLeft - 1, fullTop, fullBot - fullTop,
                            f2a(rite - left));
                }
                if (partialBot > 0) {
                    blitter->blitAntiH(fullLeft - 1, fullBot, 1,
                            f2a(SkFixedMul(partialBot, rite - left)));
                }
            }

            y = local_bot_fixed;
        } else {
            // The following constant are used to snap X
            // We snap X mainly for speedup (no tiny triangle) and
            // avoiding edge cases caused by precision errors
            const SkFixed kSnapDigit = SK_Fixed1 >> 4;
            const SkFixed kSnapHalf = kSnapDigit >> 1;
            const SkFixed kSnapMask = (-1 ^ (kSnapDigit - 1));
            left += kSnapHalf; rite += kSnapHalf; // For fast rounding

            // Number of blit_trapezoid_row calls we'll have
            int count = SkFixedCeilToInt(local_bot_fixed) - SkFixedFloorToInt(y);
            #ifdef SK_DEBUG
            total_y_cnt += count;
            frac_y_cnt += ((int)(y & 0xFFFF0000) != y);
            if ((int)(y & 0xFFFF0000) != y) {
                // SkDebugf("frac_y = %f\n", SkFixedToFloat(y));
            }
            #endif

            // If we're using mask blitter, we advance the mask row in this function
            // to save some "if" condition checks.
            SkAlpha* maskRow = nullptr;
            if (isUsingMask) {
                maskRow = static_cast<MaskAdditiveBlitter*>(blitter)->getRow(y >> 16);
            }

            // Instead of writing one loop that handles both partial-row blit_trapezoid_row
            // and full-row trapezoid_row together, we use the following 3-stage flow to
            // handle partial-row blit and full-row blit separately. It will save us much time
            // on changing y, left, and rite.
            if (count > 1) {
                if ((int)(y & 0xFFFF0000) != y) { // There's a partial-row on the top
                    count--;
                    SkFixed nextY = SkFixedCeilToFixed(y + 1);
                    SkFixed dY = nextY - y;
                    SkFixed nextLeft = left + SkFixedMul(dLeft, dY);
                    SkFixed nextRite = rite + SkFixedMul(dRite, dY);
                    SkASSERT((left & kSnapMask) >= leftBound && (rite & kSnapMask) <= riteBound &&
                            (nextLeft & kSnapMask) >= leftBound &&
                            (nextRite & kSnapMask) <= riteBound);
                    blit_trapezoid_row(blitter, y >> 16, left & kSnapMask, rite & kSnapMask,
                            nextLeft & kSnapMask, nextRite & kSnapMask, leftE->fDY, riteE->fDY,
                            getPartialAlpha(0xFF, dY), maskRow, isUsingMask);
                    blitter->flush_if_y_changed(y, nextY);
                    left = nextLeft; rite = nextRite; y = nextY;
                }

                while (count > 1) { // Full rows in the middle
                    count--;
                    if (isUsingMask) {
                        maskRow = static_cast<MaskAdditiveBlitter*>(blitter)->getRow(y >> 16);
                    }
                    SkFixed nextY = y + SK_Fixed1, nextLeft = left + dLeft, nextRite = rite + dRite;
                    SkASSERT((left & kSnapMask) >= leftBound && (rite & kSnapMask) <= riteBound &&
                            (nextLeft & kSnapMask) >= leftBound &&
                            (nextRite & kSnapMask) <= riteBound);
                    blit_trapezoid_row(blitter, y >> 16, left & kSnapMask, rite & kSnapMask,
                            nextLeft & kSnapMask, nextRite & kSnapMask,
                            leftE->fDY, riteE->fDY, 0xFF, maskRow, isUsingMask);
                    blitter->flush_if_y_changed(y, nextY);
                    left = nextLeft; rite = nextRite; y = nextY;
                }
            }

            if (isUsingMask) {
                maskRow = static_cast<MaskAdditiveBlitter*>(blitter)->getRow(y >> 16);
            }

            SkFixed dY = local_bot_fixed - y; // partial-row on the bottom
            SkASSERT(dY <= SK_Fixed1);
            // Smooth jumping to integer y may make the last nextLeft/nextRite out of bound.
            // Take them back into the bound here.
            // Note that we substract kSnapHalf later so we have to add them to leftBound/riteBound
            SkFixed nextLeft = SkTMax(left + SkFixedMul(dLeft, dY), leftBound + kSnapHalf);
            SkFixed nextRite = SkTMin(rite + SkFixedMul(dRite, dY), riteBound + kSnapHalf);
            SkASSERT((left & kSnapMask) >= leftBound && (rite & kSnapMask) <= riteBound &&
                    (nextLeft & kSnapMask) >= leftBound && (nextRite & kSnapMask) <= riteBound);
            blit_trapezoid_row(blitter, y >> 16, left & kSnapMask, rite & kSnapMask,
                    nextLeft & kSnapMask, nextRite & kSnapMask, leftE->fDY, riteE->fDY,
                    getPartialAlpha(0xFF, dY), maskRow, isUsingMask);
            blitter->flush_if_y_changed(y, local_bot_fixed);
            left = nextLeft; rite = nextRite; y = local_bot_fixed;
            left -= kSnapHalf; rite -= kSnapHalf;
        }

        leftE->fX = left;
        riteE->fX = rite;
        leftE->fY = riteE->fY = y;
    }

END_WALK:
    ;
    #ifdef SK_DEBUG
    // SkDebugf("frac_y_cnt = %d, total_y_cnt = %d\n", frac_y_cnt, total_y_cnt);
    #endif
}

///////////////////////////////////////////////////////////////////////////////

static inline void remove_edge(SkAnalyticEdge* edge) {
    edge->fPrev->fNext = edge->fNext;
    edge->fNext->fPrev = edge->fPrev;
}

static inline void insert_edge_after(SkAnalyticEdge* edge, SkAnalyticEdge* afterMe) {
    edge->fPrev = afterMe;
    edge->fNext = afterMe->fNext;
    afterMe->fNext->fPrev = edge;
    afterMe->fNext = edge;
}

static void backward_insert_edge_based_on_x(SkAnalyticEdge* edge) {
    SkFixed x = edge->fX;
    SkAnalyticEdge* prev = edge->fPrev;
    while (prev->fPrev && prev->fX > x) {
        prev = prev->fPrev;
    }
    if (prev->fNext != edge) {
        remove_edge(edge);
        insert_edge_after(edge, prev);
    }
}

static SkAnalyticEdge* backward_insert_start(SkAnalyticEdge* prev, SkFixed x) {
    while (prev->fPrev && prev->fX > x) {
        prev = prev->fPrev;
    }
    return prev;
}

static inline void updateNextNextY(SkFixed y, SkFixed nextY, SkFixed* nextNextY) {
    *nextNextY = y > nextY && y < *nextNextY ? y : *nextNextY;
}

static inline void checkIntersection(const SkAnalyticEdge* edge, SkFixed nextY, SkFixed* nextNextY)
{
    if (edge->fPrev->fPrev && edge->fPrev->fX + edge->fPrev->fDX > edge->fX + edge->fDX) {
        *nextNextY = nextY + (SK_Fixed1 >> SkAnalyticEdge::kDefaultAccuracy);
    }
}

static void insert_new_edges(SkAnalyticEdge* newEdge, SkFixed y, SkFixed* nextNextY) {
    if (newEdge->fUpperY > y) {
        updateNextNextY(newEdge->fUpperY, y, nextNextY);
        return;
    }
    SkAnalyticEdge* prev = newEdge->fPrev;
    if (prev->fX <= newEdge->fX) {
        while (newEdge->fUpperY <= y) {
            checkIntersection(newEdge, y, nextNextY);
            updateNextNextY(newEdge->fLowerY, y, nextNextY);
            newEdge = newEdge->fNext;
        }
        updateNextNextY(newEdge->fUpperY, y, nextNextY);
        return;
    }
    // find first x pos to insert
    SkAnalyticEdge* start = backward_insert_start(prev, newEdge->fX);
    //insert the lot, fixing up the links as we go
    do {
        SkAnalyticEdge* next = newEdge->fNext;
        do {
            if (start->fNext == newEdge) {
                goto nextEdge;
            }
            SkAnalyticEdge* after = start->fNext;
            if (after->fX >= newEdge->fX) {
                break;
            }
            SkASSERT(start != after);
            start = after;
        } while (true);
        remove_edge(newEdge);
        insert_edge_after(newEdge, start);
nextEdge:
        checkIntersection(newEdge, y, nextNextY);
        updateNextNextY(newEdge->fLowerY, y, nextNextY);
        start = newEdge;
        newEdge = next;
    } while (newEdge->fUpperY <= y);
    updateNextNextY(newEdge->fUpperY, y, nextNextY);
}

static void validate_edges_for_y(const SkAnalyticEdge* edge, SkFixed y) {
#ifdef SK_DEBUG
    while (edge->fUpperY <= y) {
        SkASSERT(edge->fPrev && edge->fNext);
        SkASSERT(edge->fPrev->fNext == edge);
        SkASSERT(edge->fNext->fPrev == edge);
        SkASSERT(edge->fUpperY <= edge->fLowerY);
        SkASSERT(edge->fPrev->fPrev == nullptr || edge->fPrev->fX <= edge->fX);
        edge = edge->fNext;
    }
#endif
}

// Return true if prev->fX, next->fX are too close in the current pixel row.
static inline bool edges_too_close(SkAnalyticEdge* prev, SkAnalyticEdge* next, SkFixed lowerY) {
    // Note that even if the following test failed, the edges might still be very close to each
    // other at some point within the current pixel row because of prev->fDX and next->fDX.
    // However, to handle that case, we have to sacrafice more performance.
    // I think the current quality is good enough (mainly by looking at Nebraska-StateSeal.svg)
    // so I'll ignore fDX for performance tradeoff.
    return next && prev && next->fUpperY < lowerY && prev->fX >= next->fX - SkAbs32(next->fDX);
    // The following is more accurate but also slower.
    // return (prev && prev->fPrev && next && next->fNext != nullptr && next->fUpperY < lowerY &&
    //     prev->fX + SkAbs32(prev->fDX) >= next->fX - SkAbs32(next->fDX));
}

// This function exists for the case where the previous rite edge is removed because
// its fLowerY <= nextY
static inline bool edges_too_close(int prevRite, SkFixed ul, SkFixed ll) {
    return prevRite > SkFixedFloorToInt(ul) || prevRite > SkFixedFloorToInt(ll);
}

static inline void blit_saved_trapezoid(SkAnalyticEdge* leftE, SkFixed lowerY,
        SkFixed lowerLeft, SkFixed lowerRite,
        AdditiveBlitter* blitter, SkAlpha* maskRow, bool isUsingMask, bool noRealBlitter,
        SkFixed leftClip, SkFixed rightClip) {
    SkAnalyticEdge* riteE = leftE->fRiteE;
    SkASSERT(riteE);
    SkASSERT(riteE->fNext == nullptr || leftE->fSavedY == riteE->fSavedY);
    SkASSERT(SkFixedFloorToInt(lowerY - 1) == SkFixedFloorToInt(leftE->fSavedY));
    int y = SkFixedFloorToInt(leftE->fSavedY);
    // Instead of using f2a(lowerY - leftE->fSavedY), we use the following fullAlpha
    // to elimiate cumulative error: if there are many fractional y scan lines within the
    // same row, the former may accumulate the rounding error while the later won't.
    SkAlpha fullAlpha = f2a(lowerY - SkIntToFixed(y)) - f2a(leftE->fSavedY - SkIntToFixed(y));
    // We need fSavedDY because the (quad or cubic) edge might be updated
    blit_trapezoid_row(blitter, y,
            SkTMax(leftE->fSavedX, leftClip), SkTMin(riteE->fSavedX, rightClip),
            SkTMax(lowerLeft, leftClip), SkTMin(lowerRite, rightClip),
            leftE->fSavedDY, riteE->fSavedDY, fullAlpha, maskRow, isUsingMask,
            noRealBlitter ||
                    (fullAlpha == 0xFF && (edges_too_close(leftE->fPrev, leftE, lowerY)
                            || edges_too_close(riteE, riteE->fNext, lowerY))),
            true);
    leftE->fRiteE = nullptr;
}

static inline void deferred_blit(SkAnalyticEdge* leftE, SkAnalyticEdge* riteE,
        SkFixed left, SkFixed leftDY, // don't save leftE->fX/fDY as they may have been updated
        SkFixed y, SkFixed nextY, bool isIntegralNextY, bool leftEnds, bool riteEnds,
        AdditiveBlitter* blitter, SkAlpha* maskRow, bool isUsingMask, bool noRealBlitter,
        SkFixed leftClip, SkFixed rightClip, int yShift) {
    if (leftE->fRiteE && leftE->fRiteE != riteE) {
        // leftE's right edge changed. Blit the saved trapezoid.
        SkASSERT(leftE->fRiteE->fNext == nullptr || leftE->fRiteE->fY == y);
        blit_saved_trapezoid(leftE, y, left, leftE->fRiteE->fX,
                blitter, maskRow, isUsingMask, noRealBlitter, leftClip, rightClip);
    }
    if (!leftE->fRiteE) {
        // Save and defer blitting the trapezoid
        SkASSERT(riteE->fRiteE == nullptr);
        SkASSERT(leftE->fPrev == nullptr || leftE->fY == nextY);
        SkASSERT(riteE->fNext == nullptr || riteE->fY == y);
        leftE->saveXY(left, y, leftDY);
        riteE->saveXY(riteE->fX, y, riteE->fDY);
        leftE->fRiteE = riteE;
    }
    SkASSERT(leftE->fPrev == nullptr || leftE->fY == nextY);
    riteE->goY(nextY, yShift);
    // Always blit when edges end or nextY is integral
    if (isIntegralNextY || leftEnds || riteEnds) {
        blit_saved_trapezoid(leftE, nextY, leftE->fX, riteE->fX,
                blitter, maskRow, isUsingMask, noRealBlitter, leftClip, rightClip);
    }
}

static void aaa_walk_edges(SkAnalyticEdge* prevHead, SkAnalyticEdge* nextTail,
        SkPath::FillType fillType, AdditiveBlitter* blitter, int start_y, int stop_y,
        SkFixed leftClip, SkFixed rightClip, bool isUsingMask, bool forceRLE, bool useDeferred,
        bool skipIntersect) {
    prevHead->fX = prevHead->fUpperX = leftClip;
    nextTail->fX = nextTail->fUpperX = rightClip;
    SkFixed y = SkTMax(prevHead->fNext->fUpperY, SkIntToFixed(start_y));
    SkFixed nextNextY = SK_MaxS32;

    {
        SkAnalyticEdge* edge;
        for(edge = prevHead->fNext; edge->fUpperY <= y; edge = edge->fNext) {
            edge->goY(y);
            updateNextNextY(edge->fLowerY, y, &nextNextY);
        }
        updateNextNextY(edge->fUpperY, y, &nextNextY);
    }

    // returns 1 for evenodd, -1 for winding, regardless of inverse-ness
    int windingMask = (fillType & 1) ? 1 : -1;

    bool isInverse = SkPath::IsInverseFillType(fillType);

    if (isInverse && SkIntToFixed(start_y) != y) {
        int width = SkFixedFloorToInt(rightClip - leftClip);
        if (SkFixedFloorToInt(y) != start_y) {
            blitter->getRealBlitter()->blitRect(SkFixedFloorToInt(leftClip), start_y,
                    width, SkFixedFloorToInt(y) - start_y);
            start_y = SkFixedFloorToInt(y);
        }
        SkAlpha* maskRow = isUsingMask ? static_cast<MaskAdditiveBlitter*>(blitter)->getRow(start_y)
                                       : nullptr;
        blit_full_alpha(blitter, start_y, SkFixedFloorToInt(leftClip), width,
                f2a(y - SkIntToFixed(start_y)), maskRow, isUsingMask, false, false);
    }

    while (true) {
        int     w = 0;
        bool    in_interval     = isInverse;
        SkFixed prevX           = prevHead->fX;
        SkFixed nextY           = SkTMin(nextNextY, SkFixedCeilToFixed(y + 1));
        bool isIntegralNextY    = (nextY & (SK_Fixed1 - 1)) == 0;
        SkAnalyticEdge* currE   = prevHead->fNext;
        SkAnalyticEdge* leftE   = prevHead;
        SkFixed left            = leftClip;
        SkFixed leftDY          = 0;
        bool leftEnds           = false;
        int prevRite            = SkFixedFloorToInt(leftClip);

        nextNextY               = SK_MaxS32;

        SkASSERT((nextY & ((SK_Fixed1 >> 2) - 1)) == 0);
        int yShift = 0;
        if ((nextY - y) & (SK_Fixed1 >> 2)) {
            yShift = 2;
            nextY = y + (SK_Fixed1 >> 2);
        } else if ((nextY - y) & (SK_Fixed1 >> 1)) {
            yShift = 1;
            SkASSERT(nextY == y + (SK_Fixed1 >> 1));
        }

        SkAlpha fullAlpha = f2a(nextY - y);

        // If we're using mask blitter, we advance the mask row in this function
        // to save some "if" condition checks.
        SkAlpha* maskRow = nullptr;
        if (isUsingMask) {
            maskRow = static_cast<MaskAdditiveBlitter*>(blitter)->getRow(SkFixedFloorToInt(y));
        }

        SkASSERT(currE->fPrev == prevHead);
        validate_edges_for_y(currE, y);

        // Even if next - y == SK_Fixed1, we can still break the left-to-right order requirement
        // of the SKAAClip: |\| (two trapezoids with overlapping middle wedges)
        bool noRealBlitter = forceRLE; // forceRLE && (nextY - y != SK_Fixed1);

        while (currE->fUpperY <= y) {
            SkASSERT(currE->fLowerY >= nextY);
            SkASSERT(currE->fY == y);

            w += currE->fWinding;
            bool prev_in_interval = in_interval;
            in_interval = !(w & windingMask) == isInverse;

            bool isLeft = in_interval && !prev_in_interval;
            bool isRite = !in_interval && prev_in_interval;
            bool currEnds = currE->fLowerY == nextY;

            if (useDeferred) {
                if (currE->fRiteE && !isLeft) {
                    // currE is a left edge previously, but now it's not.
                    // Blit the trapezoid between fSavedY and y.
                    SkASSERT(currE->fRiteE->fY == y);
                    blit_saved_trapezoid(currE, y, currE->fX, currE->fRiteE->fX,
                            blitter, maskRow, isUsingMask, noRealBlitter, leftClip, rightClip);
                }
                if (leftE->fRiteE == currE && !isRite) {
                    // currE is a right edge previously, but now it's not.
                    // Moreover, its corresponding leftE doesn't change (otherwise we'll handle it
                    // in the previous if clause). Hence we blit the trapezoid.
                    blit_saved_trapezoid(leftE, y, left, currE->fX,
                            blitter, maskRow, isUsingMask, noRealBlitter, leftClip, rightClip);
                }
            }

            if (isRite) {
                if (useDeferred) {
                    deferred_blit(leftE, currE, left, leftDY, y, nextY, isIntegralNextY,
                            leftEnds, currEnds, blitter, maskRow, isUsingMask, noRealBlitter,
                            leftClip, rightClip, yShift);
                } else {
                    SkFixed rite = currE->fX;
                    currE->goY(nextY, yShift);
                    if (leftE->fDX < 0) {
                        left = SkTMax(leftClip, left);
                        leftE->fX = SkTMax(leftClip, leftE->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,
                            leftDY, currE->fDY, fullAlpha, maskRow, isUsingMask,
                            noRealBlitter || (fullAlpha == 0xFF && (
                                    edges_too_close(prevRite, left, leftE->fX) ||
                                    edges_too_close(currE, currE->fNext, nextY)
                            )),
                            true);
                    prevRite = SkFixedCeilToInt(SkTMax(rite, currE->fX));
                }
            } else {
                if (isLeft) {
                    left = currE->fX;
                    leftDY = currE->fDY;
                    leftE = currE;
                    leftEnds = leftE->fLowerY == nextY;
                }
                currE->goY(nextY, yShift);
            }


            SkAnalyticEdge* next = currE->fNext;
            SkFixed newX;

            while (currE->fLowerY <= nextY) {
                if (currE->fCurveCount < 0) {
                    SkAnalyticCubicEdge* cubicEdge = (SkAnalyticCubicEdge*)currE;
                    cubicEdge->keepContinuous();
                    if (!cubicEdge->updateCubic()) {
                        break;
                    }
                } else if (currE->fCurveCount > 0) {
                    SkAnalyticQuadraticEdge* quadEdge = (SkAnalyticQuadraticEdge*)currE;
                    quadEdge->keepContinuous();
                    if (!quadEdge->updateQuadratic()) {
                        break;
                    }
                } else {
                    break;
                }
            }
            SkASSERT(currE->fY == nextY);

            if (currE->fLowerY <= nextY) {
                remove_edge(currE);
            } else {
                updateNextNextY(currE->fLowerY, nextY, &nextNextY);
                newX = currE->fX;
                SkASSERT(currE->fLowerY > nextY);
                if (newX < prevX) { // ripple currE backwards until it is x-sorted
                    // If the crossing edge is a right edge, blit the saved trapezoid.
                    if (leftE->fRiteE == currE && useDeferred) {
                        SkASSERT(leftE->fY == nextY && currE->fY == nextY);
                        blit_saved_trapezoid(leftE, nextY, leftE->fX, currE->fX,
                                blitter, maskRow, isUsingMask, noRealBlitter, leftClip, rightClip);
                    }
                    backward_insert_edge_based_on_x(currE);
                } else {
                    prevX = newX;
                }
                if (!skipIntersect) {
                   checkIntersection(currE, nextY, &nextNextY);
                }
            }

            currE = next;
            SkASSERT(currE);
        }

        // was our right-edge culled away?
        if (in_interval) {
            if (useDeferred) {
                deferred_blit(leftE, nextTail, left, leftDY, y, nextY, isIntegralNextY,
                        leftEnds, false, blitter, maskRow, isUsingMask, noRealBlitter,
                        leftClip, rightClip, yShift);
            } else {
                blit_trapezoid_row(blitter, y >> 16,
                        SkTMax(leftClip, left), rightClip,
                        SkTMax(leftClip, leftE->fX), rightClip,
                        leftDY, 0, fullAlpha, maskRow, isUsingMask,
                        noRealBlitter ||
                                (fullAlpha == 0xFF && edges_too_close(leftE->fPrev, leftE, nextY)),
                        true);
            }
        }

        if (forceRLE) {
            ((RunBasedAdditiveBlitter*)blitter)->flush_if_y_changed(y, nextY);
        }

        y = nextY;
        if (y >= SkIntToFixed(stop_y)) {
            break;
        }

        // now currE points to the first edge with a fUpperY larger than the previous y
        insert_new_edges(currE, y, &nextNextY);
    }
}

static void aaa_fill_path(const SkPath& path, const SkIRect& clipRect,
        AdditiveBlitter* blitter, int start_y, int stop_y, bool pathContainedInClip,
        bool isUsingMask, bool forceRLE) { // forceRLE implies that SkAAClip is calling us
    SkASSERT(blitter);

    SkEdgeBuilder   builder;

    // If we're convex, then we need both edges, even the right edge is past the clip
    const bool canCullToTheRight = !path.isConvex();

    SkASSERT(gSkUseAnalyticAA.load());
    const SkIRect* builderClip = pathContainedInClip ? nullptr : &clipRect;
    int count = builder.build(path, builderClip, 0, canCullToTheRight, true);
    SkASSERT(count >= 0);

    SkAnalyticEdge** list = (SkAnalyticEdge**)builder.analyticEdgeList();

    SkIRect rect = clipRect;
    if (0 == count) {
        if (path.isInverseFillType()) {
            /*
             *  Since we are in inverse-fill, our caller has already drawn above
             *  our top (start_y) and will draw below our bottom (stop_y). Thus
             *  we need to restrict our drawing to the intersection of the clip
             *  and those two limits.
             */
            if (rect.fTop < start_y) {
                rect.fTop = start_y;
            }
            if (rect.fBottom > stop_y) {
                rect.fBottom = stop_y;
            }
            if (!rect.isEmpty()) {
                blitter->getRealBlitter()->blitRect(rect.fLeft, rect.fTop,
                        rect.width(), rect.height());
            }
        }
        return;
    }

    SkAnalyticEdge headEdge, tailEdge, *last;
    // this returns the first and last edge after they're sorted into a dlink list
    SkAnalyticEdge* edge = sort_edges(list, count, &last);

    headEdge.fRiteE = nullptr;
    headEdge.fPrev = nullptr;
    headEdge.fNext = edge;
    headEdge.fUpperY = headEdge.fLowerY = SK_MinS32;
    headEdge.fX = SK_MinS32;
    headEdge.fDX = 0;
    headEdge.fDY = SK_MaxS32;
    headEdge.fUpperX = SK_MinS32;
    edge->fPrev = &headEdge;

    tailEdge.fRiteE = nullptr;
    tailEdge.fPrev = last;
    tailEdge.fNext = nullptr;
    tailEdge.fUpperY = tailEdge.fLowerY = SK_MaxS32;
    tailEdge.fX = SK_MaxS32;
    tailEdge.fDX = 0;
    tailEdge.fDY = SK_MaxS32;
    tailEdge.fUpperX = SK_MaxS32;
    last->fNext = &tailEdge;

    // now edge is the head of the sorted linklist

    if (!pathContainedInClip && start_y < clipRect.fTop) {
        start_y = clipRect.fTop;
    }
    if (!pathContainedInClip && stop_y > clipRect.fBottom) {
        stop_y = clipRect.fBottom;
    }

    SkFixed leftBound = SkIntToFixed(rect.fLeft);
    SkFixed rightBound = SkIntToFixed(rect.fRight);
    if (isUsingMask) {
        // If we're using mask, then we have to limit the bound within the path bounds.
        // Otherwise, the edge drift may access an invalid address inside the mask.
        SkIRect ir;
        path.getBounds().roundOut(&ir);
        leftBound = SkTMax(leftBound, SkIntToFixed(ir.fLeft));
        rightBound = SkTMin(rightBound, SkIntToFixed(ir.fRight));
    }

    if (!path.isInverseFillType() && path.isConvex()) {
        SkASSERT(count >= 2);   // convex walker does not handle missing right edges
        aaa_walk_convex_edges(&headEdge, blitter, start_y, stop_y,
                              leftBound, rightBound, isUsingMask);
    } else {
        // Only use deferred blitting if there are many edges.
        bool useDeferred = count >
                (SkFixedFloorToInt(tailEdge.fPrev->fLowerY - headEdge.fNext->fUpperY) + 1) * 4;

        // We skip intersection computation if there are many points which probably already
        // give us enough fractional scan lines.
        bool skipIntersect = path.countPoints() > (stop_y - start_y) / 2;

        aaa_walk_edges(&headEdge, &tailEdge, path.getFillType(), blitter, start_y, stop_y,
               leftBound, rightBound, isUsingMask, forceRLE, useDeferred, skipIntersect);
    }
}

///////////////////////////////////////////////////////////////////////////////

static int overflows_short_shift(int value, int shift) {
    const int s = 16 + shift;
    return (SkLeftShift(value, s) >> s) - value;
}

/**
  Would any of the coordinates of this rectangle not fit in a short,
  when left-shifted by shift?
*/
static int rect_overflows_short_shift(SkIRect rect, int shift) {
    SkASSERT(!overflows_short_shift(8191, 2));
    SkASSERT(overflows_short_shift(8192, 2));
    SkASSERT(!overflows_short_shift(32767, 0));
    SkASSERT(overflows_short_shift(32768, 0));

    // Since we expect these to succeed, we bit-or together
    // for a tiny extra bit of speed.
    return overflows_short_shift(rect.fLeft, 2) |
           overflows_short_shift(rect.fRight, 2) |
           overflows_short_shift(rect.fTop, 2) |
           overflows_short_shift(rect.fBottom, 2);
}

static bool fitsInsideLimit(const SkRect& r, SkScalar max) {
    const SkScalar min = -max;
    return  r.fLeft > min && r.fTop > min &&
            r.fRight < max && r.fBottom < max;
}

static bool safeRoundOut(const SkRect& src, SkIRect* dst, int32_t maxInt) {
    const SkScalar maxScalar = SkIntToScalar(maxInt);

    if (fitsInsideLimit(src, maxScalar)) {
        src.roundOut(dst);
        return true;
    }
    return false;
}

void SkScan::AAAFillPath(const SkPath& path, const SkRegion& origClip, SkBlitter* blitter,
                         bool forceRLE) {
    if (origClip.isEmpty()) {
        return;
    }
    #ifdef SK_SUPPORT_LEGACY_AAA
    if (path.isInverseFillType() || !path.isConvex()) {
        // Fall back as we only implemented the algorithm for convex shapes yet.
        SkScan::AntiFillPath(path, origClip, blitter, forceRLE);
        return;
    }
    #endif

    const bool isInverse = path.isInverseFillType();
    SkIRect ir;
    if (!safeRoundOut(path.getBounds(), &ir, SK_MaxS32 >> 2)) {
        return;
    }
    if (ir.isEmpty()) {
        if (isInverse) {
            blitter->blitRegion(origClip);
        }
        return;
    }

    SkIRect clippedIR;
    if (isInverse) {
       // If the path is an inverse fill, it's going to fill the entire
       // clip, and we care whether the entire clip exceeds our limits.
       clippedIR = origClip.getBounds();
    } else {
       if (!clippedIR.intersect(ir, origClip.getBounds())) {
           return;
       }
    }
    // If the intersection of the path bounds and the clip bounds
    // will overflow 32767 when << by 2, our SkFixed will overflow,
    // so draw without antialiasing.
    if (rect_overflows_short_shift(clippedIR, 2)) {
        SkScan::FillPath(path, origClip, blitter);
        return;
    }

    // Our antialiasing can't handle a clip larger than 32767, so we restrict
    // the clip to that limit here. (the runs[] uses int16_t for its index).
    //
    // A more general solution (one that could also eliminate the need to
    // disable aa based on ir bounds (see overflows_short_shift) would be
    // to tile the clip/target...
    SkRegion tmpClipStorage;
    const SkRegion* clipRgn = &origClip;
    {
        static const int32_t kMaxClipCoord = 32767;
        const SkIRect& bounds = origClip.getBounds();
        if (bounds.fRight > kMaxClipCoord || bounds.fBottom > kMaxClipCoord) {
            SkIRect limit = { 0, 0, kMaxClipCoord, kMaxClipCoord };
            tmpClipStorage.op(origClip, limit, SkRegion::kIntersect_Op);
            clipRgn = &tmpClipStorage;
        }
    }
    // for here down, use clipRgn, not origClip

    SkScanClipper   clipper(blitter, clipRgn, ir);
    const SkIRect*  clipRect = clipper.getClipRect();

    if (clipper.getBlitter() == nullptr) { // clipped out
        if (isInverse) {
            blitter->blitRegion(*clipRgn);
        }
        return;
    }

    // now use the (possibly wrapped) blitter
    blitter = clipper.getBlitter();

    if (isInverse) {
        sk_blit_above(blitter, ir, *clipRgn);
    }

    SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);

    if (MaskAdditiveBlitter::canHandleRect(ir) && !isInverse && !forceRLE) {
        MaskAdditiveBlitter additiveBlitter(blitter, ir, *clipRgn, isInverse);
        aaa_fill_path(path, clipRgn->getBounds(), &additiveBlitter, ir.fTop, ir.fBottom,
                clipRect == nullptr, true, forceRLE);
    } else if (!isInverse && path.isConvex()) {
        RunBasedAdditiveBlitter additiveBlitter(blitter, ir, *clipRgn, isInverse);
        aaa_fill_path(path, clipRgn->getBounds(), &additiveBlitter, ir.fTop, ir.fBottom,
                clipRect == nullptr, false, forceRLE);
    } else {
        SafeRLEAdditiveBlitter additiveBlitter(blitter, ir, *clipRgn, isInverse);
        aaa_fill_path(path, clipRgn->getBounds(), &additiveBlitter, ir.fTop, ir.fBottom,
                clipRect == nullptr, false, forceRLE);
    }

    if (isInverse) {
        sk_blit_below(blitter, ir, *clipRgn);
    }
}

// This almost copies SkScan::AntiFillPath
void SkScan::AAAFillPath(const SkPath& path, const SkRasterClip& clip, SkBlitter* blitter) {
    if (clip.isEmpty()) {
        return;
    }

    if (clip.isBW()) {
        AAAFillPath(path, clip.bwRgn(), blitter);
    } else {
        SkRegion        tmp;
        SkAAClipBlitter aaBlitter;

        tmp.setRect(clip.getBounds());
        aaBlitter.init(blitter, &clip.aaRgn());
        AAAFillPath(path, tmp, &aaBlitter, true);
    }
}
