/*
 * 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 "include/core/SkPath.h"
#include "include/core/SkRegion.h"
#include "include/private/SkTemplates.h"
#include "include/private/SkTo.h"
#include "src/core/SkAnalyticEdge.h"
#include "src/core/SkAntiRun.h"
#include "src/core/SkAutoMalloc.h"
#include "src/core/SkBlitter.h"
#include "src/core/SkEdge.h"
#include "src/core/SkEdgeBuilder.h"
#include "src/core/SkGeometry.h"
#include "src/core/SkQuadClipper.h"
#include "src/core/SkRasterClip.h"
#include "src/core/SkScan.h"
#include "src/core/SkScanPriv.h"
#include "src/core/SkTSort.h"

#include <utility>

#if defined(SK_DISABLE_AAA)
void SkScan::AAAFillPath(const SkPath&, SkBlitter*, const SkIRect&, const SkIRect&, bool) {
    SkDEBUGFAIL("AAA Disabled");
    return;
}
#else

/*

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 void add_alpha(SkAlpha* alpha, SkAlpha delta) {
    SkASSERT(*alpha + delta <= 256);
    *alpha = SkAlphaRuns::CatchOverflow(*alpha + delta);
}

static void safely_add_alpha(SkAlpha* alpha, SkAlpha delta) {
    *alpha = std::min(0xFF, *alpha + delta);
}

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

    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 SkIRect& clipBounds,
                        bool           isInverse);
    ~MaskAdditiveBlitter() override { 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)
    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 SkIRect& clipBounds,
                                         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(clipBounds)) {
        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) {
    SK_ABORT("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);
    add_alpha(&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) {
        add_alpha(&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 SkIRect& clipBounds,
                            bool           isInverse);

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

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

    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 { return fWidth; }

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

protected:
    SkBlitter* fRealBlitter;

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

    // 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;

    bool check(int x, int width) const { return x >= 0 && x + width <= fWidth; }

    // extra one to store the zero at the end
    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.
    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
    SkAlpha snapAlpha(SkAlpha alpha) { return alpha > 247 ? 0xFF : alpha < 8 ? 0x00 : alpha; }

    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;
        }
    }

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

RunBasedAdditiveBlitter::RunBasedAdditiveBlitter(SkBlitter*     realBlitter,
                                                 const SkIRect& ir,
                                                 const SkIRect& clipBounds,
                                                 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 = clipBounds;
    } else {
        if (!sectBounds.intersect(ir, clipBounds)) {
            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;
}

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 = std::min(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) {
        add_alpha(&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);
    }
}

// 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 SkIRect& clipBounds,
                           bool           isInverse)
            : RunBasedAdditiveBlitter(realBlitter, ir, clipBounds, 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 = std::min(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) {
        safely_add_alpha(&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);
        safely_add_alpha(&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]) {
            safely_add_alpha(&fRuns.fAlpha[i], alpha);
        }
    }
}

// Return the alpha of a trapezoid whose height is 1
static SkAlpha trapezoid_to_alpha(SkFixed l1, SkFixed l2) {
    SkASSERT(l1 >= 0 && l2 >= 0);
    SkFixed area = (l1 + l2) / 2;
    return SkTo<SkAlpha>(area >> 8);
}

// The alpha of right-triangle (a, a*b)
static SkAlpha partial_triangle_to_alpha(SkFixed a, SkFixed b) {
    SkASSERT(a <= SK_Fixed1);
#if 0
    // TODO(mtklein): skia:8877
    SkASSERT(b <= SK_Fixed1);
#endif

    // Approximating...
    // SkFixed area = SkFixedMul(a, SkFixedMul(a,b)) / 2;
    SkFixed area = (a >> 11) * (a >> 11) * (b >> 11);

#if 0
    // TODO(mtklein): skia:8877
    return SkTo<SkAlpha>(area >> 8);
#else
    return SkTo<SkAlpha>((area >> 8) & 0xFF);
#endif
}

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

static SkAlpha get_partial_alpha(SkAlpha alpha, SkAlpha fullAlpha) {
    return (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 SkAlpha fixed_to_alpha(SkFixed f) {
    SkASSERT(f <= SK_Fixed1);
    return get_partial_alpha(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 SkFixed approximate_intersection(SkFixed l1, SkFixed r1, SkFixed l2, SkFixed r2) {
    if (l1 > r1) {
        std::swap(l1, r1);
    }
    if (l2 > r2) {
        std::swap(l2, r2);
    }
    return (std::max(l1, l2) + std::min(r1, r2)) / 2;
}

// Here we always send in l < SK_Fixed1, and the first alpha we want to compute is alphas[0]
static void compute_alpha_above_line(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] = get_partial_alpha(((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 - partial_triangle_to_alpha(last, dY);
    }
}

// Here we always send in l < SK_Fixed1, and the first alpha we want to compute is alphas[0]
static void compute_alpha_below_line(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] = get_partial_alpha(trapezoid_to_alpha(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) & 0xFF;
            alpha16 += dY;
        }
        alphas[0] = fullAlpha - partial_triangle_to_alpha(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) {
            safely_add_alpha(&maskRow[x], get_partial_alpha(alpha, fullAlpha));
        } else {
            add_alpha(&maskRow[x], get_partial_alpha(alpha, fullAlpha));
        }
    } else {
        if (fullAlpha == 0xFF && !noRealBlitter) {
            blitter->getRealBlitter()->blitV(x, y, 1, alpha);
        } else {
            blitter->blitAntiH(x, y, get_partial_alpha(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) {
            safely_add_alpha(&maskRow[x], a1);
            safely_add_alpha(&maskRow[x + 1], a2);
        } else {
            add_alpha(&maskRow[x], a1);
            add_alpha(&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);
        }
    }
}

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) {
                safely_add_alpha(&maskRow[x + i], fullAlpha);
            } else {
                add_alpha(&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 = trapezoid_to_alpha(ur - ul, lr - ll);
        blit_single_alpha(blitter,
                          y,
                          L,
                          alpha,
                          fullAlpha,
                          maskRow,
                          isUsingMask,
                          noRealBlitter,
                          needSafeCheck);
        return;
    }

    const int kQuickLen = 31;
    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 - partial_triangle_to_alpha(first, lDY);
        SkAlpha a2     = partial_triangle_to_alpha(second, lDY);
        alphas[0]      = alphas[0] > a1 ? alphas[0] - a1 : 0;
        alphas[1]      = alphas[1] > a2 ? alphas[1] - a2 : 0;
    } else {
        compute_alpha_below_line(
                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      = partial_triangle_to_alpha(first, rDY);
        SkAlpha a2      = fullAlpha - partial_triangle_to_alpha(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 {
        compute_alpha_above_line(
                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) {
                safely_add_alpha(&maskRow[L + i], alphas[i]);
            } else {
                add_alpha(&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) {
        return;
    }

    // Edge crosses. Approximate it. This should only happend due to precision limit,
    // so the approximation could be very coarse.
    if (ll > lr) {
        ll = lr = approximate_intersection(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) {
        std::swap(ul, ll);
    }
    if (ur > lr) {
        std::swap(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 = trapezoid_to_alpha(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     = partial_triangle_to_alpha(first, lDY);
                SkAlpha a2     = fullAlpha - partial_triangle_to_alpha(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 = trapezoid_to_alpha(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 - partial_triangle_to_alpha(first, rDY);
                SkAlpha a2     = partial_triangle_to_alpha(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);

    // 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];
}

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

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

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

// 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 bool is_smooth_enough(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 bool is_smooth_enough(SkAnalyticEdge* leftE,
                             SkAnalyticEdge* riteE,
                             SkAnalyticEdge* currE,
                             int             stop_y) {
    if (currE->fUpperY >= SkLeftShift(stop_y, 16)) {
        return false;  // We're at the end so we won't skip anything
    }
    if (leftE->fLowerY + SK_Fixed1 < riteE->fLowerY) {
        return is_smooth_enough(leftE, currE, stop_y);  // Only leftE is changing
    } else if (leftE->fLowerY > riteE->fLowerY + SK_Fixed1) {
        return is_smooth_enough(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;
    }
    // Ensure that currE is the next left edge and nextCurrE is the next right edge. Swap if not.
    if (nextCurrE->fUpperX < currE->fUpperX) {
        std::swap(currE, nextCurrE);
    }
    return is_smooth_enough(leftE, currE, stop_y) && is_smooth_enough(riteE, nextCurrE, stop_y);
}

static 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 = std::max(leftE->fUpperY, riteE->fUpperY);

    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 (!leftE->update(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 (!riteE->update(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)) {
            std::swap(leftE, riteE);
        }

        SkFixed local_bot_fixed = std::min(leftE->fLowerY, riteE->fLowerY);
        if (is_smooth_enough(leftE, riteE, currE, stop_y)) {
            local_bot_fixed = SkFixedCeilToFixed(local_bot_fixed);
        }
        local_bot_fixed = std::min(local_bot_fixed, SkIntToFixed(stop_y));

        SkFixed left  = std::max(leftBound, leftE->fX);
        SkFixed dLeft = leftE->fDX;
        SkFixed rite  = std::min(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,
                                           fixed_to_alpha(SkFixedMul(partialTop, partialLeft)));
                    }
                    blitter->blitAntiH(
                            fullLeft, fullTop - 1, fullRite - fullLeft, fixed_to_alpha(partialTop));
                    if (partialRite > 0) {
                        blitter->blitAntiH(fullRite,
                                           fullTop - 1,
                                           fixed_to_alpha(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 || fixed_to_alpha(partialLeft) > 0 ||
                     fixed_to_alpha(partialRite) > 0)) {
                    blitter->getRealBlitter()->blitAntiRect(fullLeft - 1,
                                                            fullTop,
                                                            fullRite - fullLeft,
                                                            fullBot - fullTop,
                                                            fixed_to_alpha(partialLeft),
                                                            fixed_to_alpha(partialRite));
                }

                if (partialBot > 0) {  // blit last partial row
                    if (partialLeft > 0) {
                        blitter->blitAntiH(fullLeft - 1,
                                           fullBot,
                                           fixed_to_alpha(SkFixedMul(partialBot, partialLeft)));
                    }
                    blitter->blitAntiH(
                            fullLeft, fullBot, fullRite - fullLeft, fixed_to_alpha(partialBot));
                    if (partialRite > 0) {
                        blitter->blitAntiH(fullRite,
                                           fullBot,
                                           fixed_to_alpha(SkFixedMul(partialBot, partialRite)));
                    }
                }
            } else {
                // Normal conditions, this means left and rite are within the same pixel, but if
                // both left and rite were < leftBounds or > rightBounds, both edges are clipped and
                // we should not do any blitting (particularly since the negative width saturates to
                // full alpha).
                SkFixed width = rite - left;
                if (width > 0) {
                    if (partialTop > 0) {
                        blitter->blitAntiH(fullLeft - 1,
                                           fullTop - 1,
                                           1,
                                           fixed_to_alpha(SkFixedMul(partialTop, width)));
                        blitter->flush_if_y_changed(y, y + partialTop);
                    }
                    if (fullBot > fullTop) {
                        blitter->getRealBlitter()->blitV(
                                fullLeft - 1, fullTop, fullBot - fullTop, fixed_to_alpha(width));
                    }
                    if (partialBot > 0) {
                        blitter->blitAntiH(fullLeft - 1,
                                           fullBot,
                                           1,
                                           fixed_to_alpha(SkFixedMul(partialBot, width)));
                    }
                }
            }

            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);

            // 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,
                                       get_partial_alpha(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 = std::max(left + SkFixedMul(dLeft, dY), leftBound + kSnapHalf);
            SkFixed nextRite = std::min(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,
                               get_partial_alpha(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:;
}

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

static void check_intersection(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) {
        update_next_next_y(newEdge->fUpperY, y, nextNextY);
        return;
    }
    SkAnalyticEdge* prev = newEdge->fPrev;
    if (prev->fX <= newEdge->fX) {
        while (newEdge->fUpperY <= y) {
            check_intersection(newEdge, y, nextNextY);
            update_next_next_y(newEdge->fLowerY, y, nextNextY);
            newEdge = newEdge->fNext;
        }
        update_next_next_y(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:
        check_intersection(newEdge, y, nextNextY);
        update_next_next_y(newEdge->fLowerY, y, nextNextY);
        start   = newEdge;
        newEdge = next;
    } while (newEdge->fUpperY <= y);
    update_next_next_y(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 bool edges_too_close(SkAnalyticEdge* prev, SkAnalyticEdge* next, SkFixed lowerY) {
    // When next->fDX == 0, prev->fX >= next->fX - SkAbs32(next->fDX) would be false
    // even if prev->fX and next->fX are close and within one pixel (e.g., prev->fX == 0.1,
    // next->fX == 0.9). Adding SLACK = 1 to the formula would guarantee it to be true if two
    // edges prev and next are within one pixel.
    constexpr SkFixed SLACK = SK_Fixed1;

    // 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 + SLACK >= 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) + SLACK >= next->fX - SkAbs32(next->fDX));
}

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

static 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 fixed_to_alpha(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 = fixed_to_alpha(lowerY - SkIntToFixed(y)) -
                        fixed_to_alpha(leftE->fSavedY - SkIntToFixed(y));
    // We need fSavedDY because the (quad or cubic) edge might be updated
    blit_trapezoid_row(
            blitter,
            y,
            std::max(leftE->fSavedX, leftClip),
            std::min(riteE->fSavedX, rightClip),
            std::max(lowerLeft, leftClip),
            std::min(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 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,
                           SkPathFillType   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                        = std::max(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);
            update_next_next_y(edge->fLowerY, y, &nextNextY);
        }
        update_next_next_y(edge->fUpperY, y, &nextNextY);
    }

    int windingMask = SkPathFillType_IsEvenOdd(fillType) ? 1 : -1;
    bool isInverse  = SkPathFillType_IsInverse(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,
                        fixed_to_alpha(y - SkIntToFixed(start_y)),
                        maskRow,
                        isUsingMask,
                        false,
                        false);
    }

    while (true) {
        int             w               = 0;
        bool            in_interval     = isInverse;
        SkFixed         prevX           = prevHead->fX;
        SkFixed         nextY           = std::min(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 = fixed_to_alpha(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);
                    SkFixed nextLeft = std::max(leftClip, leftE->fX);
                    rite             = std::min(rightClip, rite);
                    SkFixed nextRite = std::min(rightClip, currE->fX);
                    blit_trapezoid_row(
                            blitter,
                            y >> 16,
                            left,
                            rite,
                            nextLeft,
                            nextRite,
                            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(std::max(rite, currE->fX));
                }
            } else {
                if (isLeft) {
                    left     = std::max(currE->fX, leftClip);
                    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 {
                update_next_next_y(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) {
                    check_intersection(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,
                                   left,
                                   rightClip,
                                   std::max(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 SK_ALWAYS_INLINE 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);

    SkAnalyticEdgeBuilder builder;
    int              count = builder.buildEdges(path, pathContainedInClip ? nullptr : &clipRect);
    SkAnalyticEdge** list  = 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  = std::max(leftBound, SkIntToFixed(ir.fLeft));
        rightBound = std::min(rightBound, SkIntToFixed(ir.fRight));
    }

    if (!path.isInverseFillType() && path.isConvex() && count >= 2) {
        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);
    }
}

void SkScan::AAAFillPath(const SkPath&  path,
                         SkBlitter*     blitter,
                         const SkIRect& ir,
                         const SkIRect& clipBounds,
                         bool           forceRLE) {
    bool containedInClip = clipBounds.contains(ir);
    bool isInverse       = path.isInverseFillType();

    // The mask blitter (where we store intermediate alpha values directly in a mask, and then call
    // the real blitter once in the end to blit the whole mask) is faster than the RLE blitter when
    // the blit region is small enough (i.e., CanHandleRect(ir)). When isInverse is true, the blit
    // region is no longer the rectangle ir so we won't use the mask blitter. The caller may also
    // use the forceRLE flag to force not using the mask blitter. Also, when the path is a simple
    // rect, preparing a mask and blitting it might have too much overhead. Hence we'll use
    // blitFatAntiRect to avoid the mask and its overhead.
    if (MaskAdditiveBlitter::CanHandleRect(ir) && !isInverse && !forceRLE) {
        // blitFatAntiRect is slower than the normal AAA flow without MaskAdditiveBlitter.
        // Hence only tryBlitFatAntiRect when MaskAdditiveBlitter would have been used.
        if (!TryBlitFatAntiRect(blitter, path, clipBounds)) {
            MaskAdditiveBlitter additiveBlitter(blitter, ir, clipBounds, isInverse);
            aaa_fill_path(path,
                          clipBounds,
                          &additiveBlitter,
                          ir.fTop,
                          ir.fBottom,
                          containedInClip,
                          true,
                          forceRLE);
        }
    } else if (!isInverse && path.isConvex()) {
        // If the filling area is convex (i.e., path.isConvex && !isInverse), our simpler
        // aaa_walk_convex_edges won't generate alphas above 255. Hence we don't need
        // SafeRLEAdditiveBlitter (which is slow due to clamping). The basic RLE blitter
        // RunBasedAdditiveBlitter would suffice.
        RunBasedAdditiveBlitter additiveBlitter(blitter, ir, clipBounds, isInverse);
        aaa_fill_path(path,
                      clipBounds,
                      &additiveBlitter,
                      ir.fTop,
                      ir.fBottom,
                      containedInClip,
                      false,
                      forceRLE);
    } else {
        // If the filling area might not be convex, the more involved aaa_walk_edges would
        // be called and we have to clamp the alpha downto 255. The SafeRLEAdditiveBlitter
        // does that at a cost of performance.
        SafeRLEAdditiveBlitter additiveBlitter(blitter, ir, clipBounds, isInverse);
        aaa_fill_path(path,
                      clipBounds,
                      &additiveBlitter,
                      ir.fTop,
                      ir.fBottom,
                      containedInClip,
                      false,
                      forceRLE);
    }
}
#endif  // defined(SK_DISABLE_AAA)
