/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrCCFillGeometry.h"

#include "GrTypes.h"
#include "SkGeometry.h"
#include <algorithm>
#include <cmath>
#include <cstdlib>

static constexpr float kFlatnessThreshold = 1/16.f; // 1/16 of a pixel.

void GrCCFillGeometry::beginPath() {
    SkASSERT(!fBuildingContour);
    fVerbs.push_back(Verb::kBeginPath);
}

void GrCCFillGeometry::beginContour(const SkPoint& pt) {
    SkASSERT(!fBuildingContour);
    // Store the current verb count in the fTriangles field for now. When we close the contour we
    // will use this value to calculate the actual number of triangles in its fan.
    fCurrContourTallies = {fVerbs.count(), 0, 0, 0, 0};

    fPoints.push_back(pt);
    fVerbs.push_back(Verb::kBeginContour);
    fCurrAnchorPoint = pt;

    SkDEBUGCODE(fBuildingContour = true);
}

void GrCCFillGeometry::lineTo(const SkPoint P[2]) {
    SkASSERT(fBuildingContour);
    SkASSERT(P[0] == fPoints.back());
    Sk2f p0 = Sk2f::Load(P);
    Sk2f p1 = Sk2f::Load(P+1);
    this->appendLine(p0, p1);
}

inline void GrCCFillGeometry::appendLine(const Sk2f& p0, const Sk2f& p1) {
    SkASSERT(fPoints.back() == SkPoint::Make(p0[0], p0[1]));
    if ((p0 == p1).allTrue()) {
        return;
    }
    p1.store(&fPoints.push_back());
    fVerbs.push_back(Verb::kLineTo);
}

static inline Sk2f normalize(const Sk2f& n) {
    Sk2f nn = n*n;
    return n * (nn + SkNx_shuffle<1,0>(nn)).rsqrt();
}

static inline float dot(const Sk2f& a, const Sk2f& b) {
    float product[2];
    (a * b).store(product);
    return product[0] + product[1];
}

static inline bool are_collinear(const Sk2f& p0, const Sk2f& p1, const Sk2f& p2,
                                 float tolerance = kFlatnessThreshold) {
    Sk2f l = p2 - p0; // Line from p0 -> p2.

    // lwidth = Manhattan width of l.
    Sk2f labs = l.abs();
    float lwidth = labs[0] + labs[1];

    // d = |p1 - p0| dot | l.y|
    //                   |-l.x| = distance from p1 to l.
    Sk2f dd = (p1 - p0) * SkNx_shuffle<1,0>(l);
    float d = dd[0] - dd[1];

    // We are collinear if a box with radius "tolerance", centered on p1, touches the line l.
    // To decide this, we check if the distance from p1 to the line is less than the distance from
    // p1 to the far corner of this imaginary box, along that same normal vector.
    // The far corner of the box can be found at "p1 + sign(n) * tolerance", where n is normal to l:
    //
    //   abs(dot(p1 - p0, n)) <= dot(sign(n) * tolerance, n)
    //
    // Which reduces to:
    //
    //   abs(d) <= (n.x * sign(n.x) + n.y * sign(n.y)) * tolerance
    //   abs(d) <= (abs(n.x) + abs(n.y)) * tolerance
    //
    // Use "<=" in case l == 0.
    return std::abs(d) <= lwidth * tolerance;
}

static inline bool are_collinear(const SkPoint P[4], float tolerance = kFlatnessThreshold) {
    Sk4f Px, Py;               // |Px  Py|   |p0 - p3|
    Sk4f::Load2(P, &Px, &Py);  // |.   . | = |p1 - p3|
    Px -= Px[3];               // |.   . |   |p2 - p3|
    Py -= Py[3];               // |.   . |   |   0   |

    // Find [lx, ly] = the line from p3 to the furthest-away point from p3.
    Sk4f Pwidth = Px.abs() + Py.abs(); // Pwidth = Manhattan width of each point.
    int lidx = Pwidth[0] > Pwidth[1] ? 0 : 1;
    lidx = Pwidth[lidx] > Pwidth[2] ? lidx : 2;
    float lx = Px[lidx], ly = Py[lidx];
    float lwidth = Pwidth[lidx]; // lwidth = Manhattan width of [lx, ly].

    //     |Px  Py|
    // d = |.   . | * | ly| = distances from each point to l (two of the distances will be zero).
    //     |.   . |   |-lx|
    //     |.   . |
    Sk4f d = Px*ly - Py*lx;

    // We are collinear if boxes with radius "tolerance", centered on all 4 points all touch line l.
    // (See the rationale for this formula in the above, 3-point version of this function.)
    // Use "<=" in case l == 0.
    return (d.abs() <= lwidth * tolerance).allTrue();
}

// Returns whether the (convex) curve segment is monotonic with respect to [endPt - startPt].
static inline bool is_convex_curve_monotonic(const Sk2f& startPt, const Sk2f& tan0,
                                             const Sk2f& endPt, const Sk2f& tan1) {
    Sk2f v = endPt - startPt;
    float dot0 = dot(tan0, v);
    float dot1 = dot(tan1, v);

    // A small, negative tolerance handles floating-point error in the case when one tangent
    // approaches 0 length, meaning the (convex) curve segment is effectively a flat line.
    float tolerance = -std::max(std::abs(dot0), std::abs(dot1)) * SK_ScalarNearlyZero;
    return dot0 >= tolerance && dot1 >= tolerance;
}

template<int N> static inline SkNx<N,float> lerp(const SkNx<N,float>& a, const SkNx<N,float>& b,
                                                 const SkNx<N,float>& t) {
    return SkNx_fma(t, b - a, a);
}

void GrCCFillGeometry::quadraticTo(const SkPoint P[3]) {
    SkASSERT(fBuildingContour);
    SkASSERT(P[0] == fPoints.back());
    Sk2f p0 = Sk2f::Load(P);
    Sk2f p1 = Sk2f::Load(P+1);
    Sk2f p2 = Sk2f::Load(P+2);

    // Don't crunch on the curve if it is nearly flat (or just very small). Flat curves can break
    // The monotonic chopping math.
    if (are_collinear(p0, p1, p2)) {
        this->appendLine(p0, p2);
        return;
    }

    this->appendQuadratics(p0, p1, p2);
}

inline void GrCCFillGeometry::appendQuadratics(const Sk2f& p0, const Sk2f& p1, const Sk2f& p2) {
    Sk2f tan0 = p1 - p0;
    Sk2f tan1 = p2 - p1;

    // This should almost always be this case for well-behaved curves in the real world.
    if (is_convex_curve_monotonic(p0, tan0, p2, tan1)) {
        this->appendMonotonicQuadratic(p0, p1, p2);
        return;
    }

    // Chop the curve into two segments with equal curvature. To do this we find the T value whose
    // tangent angle is halfway between tan0 and tan1.
    Sk2f n = normalize(tan0) - normalize(tan1);

    // The midtangent can be found where (dQ(t) dot n) = 0:
    //
    //   0 = (dQ(t) dot n) = | 2*t  1 | * | p0 - 2*p1 + p2 | * | n |
    //                                    | -2*p0 + 2*p1   |   | . |
    //
    //                     = | 2*t  1 | * | tan1 - tan0 | * | n |
    //                                    | 2*tan0      |   | . |
    //
    //                     = 2*t * ((tan1 - tan0) dot n) + (2*tan0 dot n)
    //
    //   t = (tan0 dot n) / ((tan0 - tan1) dot n)
    Sk2f dQ1n = (tan0 - tan1) * n;
    Sk2f dQ0n = tan0 * n;
    Sk2f t = (dQ0n + SkNx_shuffle<1,0>(dQ0n)) / (dQ1n + SkNx_shuffle<1,0>(dQ1n));
    t = Sk2f::Min(Sk2f::Max(t, 0), 1); // Clamp for FP error.

    Sk2f p01 = SkNx_fma(t, tan0, p0);
    Sk2f p12 = SkNx_fma(t, tan1, p1);
    Sk2f p012 = lerp(p01, p12, t);

    this->appendMonotonicQuadratic(p0, p01, p012);
    this->appendMonotonicQuadratic(p012, p12, p2);
}

inline void GrCCFillGeometry::appendMonotonicQuadratic(const Sk2f& p0, const Sk2f& p1,
                                                       const Sk2f& p2) {
    // Don't send curves to the GPU if we know they are nearly flat (or just very small).
    if (are_collinear(p0, p1, p2)) {
        this->appendLine(p0, p2);
        return;
    }

    SkASSERT(fPoints.back() == SkPoint::Make(p0[0], p0[1]));
    SkASSERT((p0 != p2).anyTrue());
    p1.store(&fPoints.push_back());
    p2.store(&fPoints.push_back());
    fVerbs.push_back(Verb::kMonotonicQuadraticTo);
    ++fCurrContourTallies.fQuadratics;
}

static inline Sk2f first_unless_nearly_zero(const Sk2f& a, const Sk2f& b) {
    Sk2f aa = a*a;
    aa += SkNx_shuffle<1,0>(aa);
    SkASSERT(aa[0] == aa[1]);

    Sk2f bb = b*b;
    bb += SkNx_shuffle<1,0>(bb);
    SkASSERT(bb[0] == bb[1]);

    return (aa > bb * SK_ScalarNearlyZero).thenElse(a, b);
}

static inline void get_cubic_tangents(const Sk2f& p0, const Sk2f& p1, const Sk2f& p2,
                                      const Sk2f& p3, Sk2f* tan0, Sk2f* tan1) {
    *tan0 = first_unless_nearly_zero(p1 - p0, p2 - p0);
    *tan1 = first_unless_nearly_zero(p3 - p2, p3 - p1);
}

static inline bool is_cubic_nearly_quadratic(const Sk2f& p0, const Sk2f& p1, const Sk2f& p2,
                                             const Sk2f& p3, const Sk2f& tan0, const Sk2f& tan1,
                                             Sk2f* c) {
    Sk2f c1 = SkNx_fma(Sk2f(1.5f), tan0, p0);
    Sk2f c2 = SkNx_fma(Sk2f(-1.5f), tan1, p3);
    *c = (c1 + c2) * .5f; // Hopefully optimized out if not used?
    return ((c1 - c2).abs() <= 1).allTrue();
}

enum class ExcludedTerm : bool {
    kQuadraticTerm,
    kLinearTerm
};

// Finds where to chop a non-loop around its inflection points. The resulting cubic segments will be
// chopped such that a box of radius 'padRadius', centered at any point along the curve segment, is
// guaranteed to not cross the tangent lines at the inflection points (a.k.a lines L & M).
//
// 'chops' will be filled with 0, 2, or 4 T values. The segments between T0..T1 and T2..T3 must be
// drawn with flat lines instead of cubics.
//
// A serpentine cubic has two inflection points, so this method takes Sk2f and computes the padding
// for both in SIMD.
static inline void find_chops_around_inflection_points(float padRadius, Sk2f tl, Sk2f sl,
                                                       const Sk2f& C0, const Sk2f& C1,
                                                       ExcludedTerm skipTerm, float Cdet,
                                                       SkSTArray<4, float>* chops) {
    SkASSERT(chops->empty());
    SkASSERT(padRadius >= 0);

    padRadius /= std::abs(Cdet); // Scale this single value rather than all of C^-1 later on.

    // The homogeneous parametric functions for distance from lines L & M are:
    //
    //     l(t,s) = (t*sl - s*tl)^3
    //     m(t,s) = (t*sm - s*tm)^3
    //
    // See "Resolution Independent Curve Rendering using Programmable Graphics Hardware",
    // 4.3 Finding klmn:
    //
    // https://www.microsoft.com/en-us/research/wp-content/uploads/2005/01/p1000-loop.pdf
    //
    // From here on we use Sk2f with "L" names, but the second lane will be for line M.
    tl = (sl > 0).thenElse(tl, -tl); // Tl=tl/sl is the triple root of l(t,s). Normalize so s >= 0.
    sl = sl.abs();

    // Convert l(t,s), m(t,s) to power-basis form:
    //
    //                                                  | l3  m3 |
    //    |l(t,s)  m(t,s)| = |t^3  t^2*s  t*s^2  s^3| * | l2  m2 |
    //                                                  | l1  m1 |
    //                                                  | l0  m0 |
    //
    Sk2f l3 = sl*sl*sl;
    Sk2f l2or1 = (ExcludedTerm::kLinearTerm == skipTerm) ? sl*sl*tl*-3 : sl*tl*tl*3;

    // The equation for line L can be found as follows:
    //
    //     L = C^-1 * (l excluding skipTerm)
    //
    // (See comments for GrPathUtils::calcCubicInverseTransposePowerBasisMatrix.)
    // We are only interested in the normal to L, so only need the upper 2x2 of C^-1. And rather
    // than divide by determinant(C) here, we have already performed this divide on padRadius.
    Sk2f Lx =  C1[1]*l3 - C0[1]*l2or1;
    Sk2f Ly = -C1[0]*l3 + C0[0]*l2or1;

    // A box of radius "padRadius" is touching line L if "center dot L" is less than the Manhattan
    // with of L. (See rationale in are_collinear.)
    Sk2f Lwidth = Lx.abs() + Ly.abs();
    Sk2f pad = Lwidth * padRadius;

    // Will T=(t + cbrt(pad))/s be greater than 0? No need to solve roots outside T=0..1.
    Sk2f insideLeftPad = pad + tl*tl*tl;

    // Will T=(t - cbrt(pad))/s be less than 1? No need to solve roots outside T=0..1.
    Sk2f tms = tl - sl;
    Sk2f insideRightPad = pad - tms*tms*tms;

    // Solve for the T values where abs(l(T)) = pad.
    if (insideLeftPad[0] > 0 && insideRightPad[0] > 0) {
        float padT = cbrtf(pad[0]);
        Sk2f pts = (tl[0] + Sk2f(-padT, +padT)) / sl[0];
        pts.store(chops->push_back_n(2));
    }

    // Solve for the T values where abs(m(T)) = pad.
    if (insideLeftPad[1] > 0 && insideRightPad[1] > 0) {
        float padT = cbrtf(pad[1]);
        Sk2f pts = (tl[1] + Sk2f(-padT, +padT)) / sl[1];
        pts.store(chops->push_back_n(2));
    }
}

static inline void swap_if_greater(float& a, float& b) {
    if (a > b) {
        std::swap(a, b);
    }
}

// Finds where to chop a non-loop around its intersection point. The resulting cubic segments will
// be chopped such that a box of radius 'padRadius', centered at any point along the curve segment,
// is guaranteed to not cross the tangent lines at the intersection point (a.k.a lines L & M).
//
// 'chops' will be filled with 0, 2, or 4 T values. The segments between T0..T1 and T2..T3 must be
// drawn with quadratic splines instead of cubics.
//
// A loop intersection falls at two different T values, so this method takes Sk2f and computes the
// padding for both in SIMD.
static inline void find_chops_around_loop_intersection(float padRadius, Sk2f t2, Sk2f s2,
                                                       const Sk2f& C0, const Sk2f& C1,
                                                       ExcludedTerm skipTerm, float Cdet,
                                                       SkSTArray<4, float>* chops) {
    SkASSERT(chops->empty());
    SkASSERT(padRadius >= 0);

    padRadius /= std::abs(Cdet); // Scale this single value rather than all of C^-1 later on.

    // The parametric functions for distance from lines L & M are:
    //
    //     l(T) = (T - Td)^2 * (T - Te)
    //     m(T) = (T - Td) * (T - Te)^2
    //
    // See "Resolution Independent Curve Rendering using Programmable Graphics Hardware",
    // 4.3 Finding klmn:
    //
    // https://www.microsoft.com/en-us/research/wp-content/uploads/2005/01/p1000-loop.pdf
    Sk2f T2 = t2/s2; // T2 is the double root of l(T).
    Sk2f T1 = SkNx_shuffle<1,0>(T2); // T1 is the other root of l(T).

    // Convert l(T), m(T) to power-basis form:
    //
    //                                      |  1   1 |
    //    |l(T)  m(T)| = |T^3  T^2  T  1| * | l2  m2 |
    //                                      | l1  m1 |
    //                                      | l0  m0 |
    //
    // From here on we use Sk2f with "L" names, but the second lane will be for line M.
    Sk2f l2 = SkNx_fma(Sk2f(-2), T2, -T1);
    Sk2f l1 = T2 * SkNx_fma(Sk2f(2), T1, T2);
    Sk2f l0 = -T2*T2*T1;

    // The equation for line L can be found as follows:
    //
    //     L = C^-1 * (l excluding skipTerm)
    //
    // (See comments for GrPathUtils::calcCubicInverseTransposePowerBasisMatrix.)
    // We are only interested in the normal to L, so only need the upper 2x2 of C^-1. And rather
    // than divide by determinant(C) here, we have already performed this divide on padRadius.
    Sk2f l2or1 = (ExcludedTerm::kLinearTerm == skipTerm) ? l2 : l1;
    Sk2f Lx = -C0[1]*l2or1 + C1[1]; // l3 is always 1.
    Sk2f Ly =  C0[0]*l2or1 - C1[0];

    // A box of radius "padRadius" is touching line L if "center dot L" is less than the Manhattan
    // with of L. (See rationale in are_collinear.)
    Sk2f Lwidth = Lx.abs() + Ly.abs();
    Sk2f pad = Lwidth * padRadius;

    // Is l(T=0) outside the padding around line L?
    Sk2f lT0 = l0; // l(T=0) = |0  0  0  1| dot |1  l2  l1  l0| = l0
    Sk2f outsideT0 = lT0.abs() - pad;

    // Is l(T=1) outside the padding around line L?
    Sk2f lT1 = (Sk2f(1) + l2 + l1 + l0).abs(); // l(T=1) = |1  1  1  1| dot |1  l2  l1  l0|
    Sk2f outsideT1 = lT1.abs() - pad;

    // Values for solving the cubic.
    Sk2f p, q, qqq, discr, numRoots, D;
    bool hasDiscr = false;

    // Values for calculating one root (rarely needed).
    Sk2f R, QQ;
    bool hasOneRootVals = false;

    // Values for calculating three roots.
    Sk2f P, cosTheta3;
    bool hasThreeRootVals = false;

    // Solve for the T values where l(T) = +pad and m(T) = -pad.
    for (int i = 0; i < 2; ++i) {
        float T = T2[i]; // T is the point we are chopping around.
        if ((T < 0 && outsideT0[i] >= 0) || (T > 1 && outsideT1[i] >= 0)) {
            // The padding around T is completely out of range. No point solving for it.
            continue;
        }

        if (!hasDiscr) {
            p = Sk2f(+.5f, -.5f) * pad;
            q = (1.f/3) * (T2 - T1);
            qqq = q*q*q;
            discr = qqq*p*2 + p*p;
            numRoots = (discr < 0).thenElse(3, 1);
            D = T2 - q;
            hasDiscr = true;
        }

        if (1 == numRoots[i]) {
            if (!hasOneRootVals) {
                Sk2f r = qqq + p;
                Sk2f s = r.abs() + discr.sqrt();
                R = (r > 0).thenElse(-s, s);
                QQ = q*q;
                hasOneRootVals = true;
            }

            float A = cbrtf(R[i]);
            float B = A != 0 ? QQ[i]/A : 0;
            // When there is only one root, ine L chops from root..1, line M chops from 0..root.
            if (1 == i) {
                chops->push_back(0);
            }
            chops->push_back(A + B + D[i]);
            if (0 == i) {
                chops->push_back(1);
            }
            continue;
        }

        if (!hasThreeRootVals) {
            P = q.abs() * -2;
            cosTheta3 = (q >= 0).thenElse(1, -1) + p / qqq.abs();
            hasThreeRootVals = true;
        }

        static constexpr float k2PiOver3 = 2 * SK_ScalarPI / 3;
        float theta = std::acos(cosTheta3[i]) * (1.f/3);
        float roots[3] = {P[i] * std::cos(theta) + D[i],
                          P[i] * std::cos(theta + k2PiOver3) + D[i],
                          P[i] * std::cos(theta - k2PiOver3) + D[i]};

        // Sort the three roots.
        swap_if_greater(roots[0], roots[1]);
        swap_if_greater(roots[1], roots[2]);
        swap_if_greater(roots[0], roots[1]);

        // Line L chops around the first 2 roots, line M chops around the second 2.
        chops->push_back_n(2, &roots[i]);
    }
}

void GrCCFillGeometry::cubicTo(const SkPoint P[4], float inflectPad, float loopIntersectPad) {
    SkASSERT(fBuildingContour);
    SkASSERT(P[0] == fPoints.back());

    // Don't crunch on the curve or inflate geometry if it is nearly flat (or just very small).
    // Flat curves can break the math below.
    if (are_collinear(P)) {
        Sk2f p0 = Sk2f::Load(P);
        Sk2f p3 = Sk2f::Load(P+3);
        this->appendLine(p0, p3);
        return;
    }

    Sk2f p0 = Sk2f::Load(P);
    Sk2f p1 = Sk2f::Load(P+1);
    Sk2f p2 = Sk2f::Load(P+2);
    Sk2f p3 = Sk2f::Load(P+3);

    // Also detect near-quadratics ahead of time.
    Sk2f tan0, tan1, c;
    get_cubic_tangents(p0, p1, p2, p3, &tan0, &tan1);
    if (is_cubic_nearly_quadratic(p0, p1, p2, p3, tan0, tan1, &c)) {
        this->appendQuadratics(p0, c, p3);
        return;
    }

    double tt[2], ss[2], D[4];
    fCurrCubicType = SkClassifyCubic(P, tt, ss, D);
    SkASSERT(!SkCubicIsDegenerate(fCurrCubicType));
    Sk2f t = Sk2f(static_cast<float>(tt[0]), static_cast<float>(tt[1]));
    Sk2f s = Sk2f(static_cast<float>(ss[0]), static_cast<float>(ss[1]));

    ExcludedTerm skipTerm = (std::abs(D[2]) > std::abs(D[1]))
                                    ? ExcludedTerm::kQuadraticTerm
                                    : ExcludedTerm::kLinearTerm;
    Sk2f C0 = SkNx_fma(Sk2f(3), p1 - p2, p3 - p0);
    Sk2f C1 = (ExcludedTerm::kLinearTerm == skipTerm
                       ? SkNx_fma(Sk2f(-2), p1, p0 + p2)
                       : p1 - p0) * 3;
    Sk2f C0x1 = C0 * SkNx_shuffle<1,0>(C1);
    float Cdet = C0x1[0] - C0x1[1];

    SkSTArray<4, float> chops;
    if (SkCubicType::kLoop != fCurrCubicType) {
        find_chops_around_inflection_points(inflectPad, t, s, C0, C1, skipTerm, Cdet, &chops);
    } else {
        find_chops_around_loop_intersection(loopIntersectPad, t, s, C0, C1, skipTerm, Cdet, &chops);
    }
    if (4 == chops.count() && chops[1] >= chops[2]) {
        // This just the means the KLM roots are so close that their paddings overlap. We will
        // approximate the entire middle section, but still have it chopped midway. For loops this
        // chop guarantees the append code only sees convex segments. Otherwise, it means we are (at
        // least almost) a cusp and the chop makes sure we get a sharp point.
        Sk2f ts = t * SkNx_shuffle<1,0>(s);
        chops[1] = chops[2] = (ts[0] + ts[1]) / (2*s[0]*s[1]);
    }

#ifdef SK_DEBUG
    for (int i = 1; i < chops.count(); ++i) {
        SkASSERT(chops[i] >= chops[i - 1]);
    }
#endif
    this->appendCubics(AppendCubicMode::kLiteral, p0, p1, p2, p3, chops.begin(), chops.count());
}

static inline void chop_cubic(const Sk2f& p0, const Sk2f& p1, const Sk2f& p2, const Sk2f& p3,
                              float T, Sk2f* ab, Sk2f* abc, Sk2f* abcd, Sk2f* bcd, Sk2f* cd) {
    Sk2f TT = T;
    *ab = lerp(p0, p1, TT);
    Sk2f bc = lerp(p1, p2, TT);
    *cd = lerp(p2, p3, TT);
    *abc = lerp(*ab, bc, TT);
    *bcd = lerp(bc, *cd, TT);
    *abcd = lerp(*abc, *bcd, TT);
}

void GrCCFillGeometry::appendCubics(AppendCubicMode mode, const Sk2f& p0, const Sk2f& p1,
                                    const Sk2f& p2, const Sk2f& p3, const float chops[],
                                    int numChops, float localT0, float localT1) {
    if (numChops) {
        SkASSERT(numChops > 0);
        int midChopIdx = numChops/2;
        float T = chops[midChopIdx];
        // Chops alternate between literal and approximate mode.
        AppendCubicMode rightMode = (AppendCubicMode)((bool)mode ^ (midChopIdx & 1) ^ 1);

        if (T <= localT0) {
            // T is outside 0..1. Append the right side only.
            this->appendCubics(rightMode, p0, p1, p2, p3, &chops[midChopIdx + 1],
                               numChops - midChopIdx - 1, localT0, localT1);
            return;
        }

        if (T >= localT1) {
            // T is outside 0..1. Append the left side only.
            this->appendCubics(mode, p0, p1, p2, p3, chops, midChopIdx, localT0, localT1);
            return;
        }

        float localT = (T - localT0) / (localT1 - localT0);
        Sk2f p01, p02, pT, p11, p12;
        chop_cubic(p0, p1, p2, p3, localT, &p01, &p02, &pT, &p11, &p12);
        this->appendCubics(mode, p0, p01, p02, pT, chops, midChopIdx, localT0, T);
        this->appendCubics(rightMode, pT, p11, p12, p3, &chops[midChopIdx + 1],
                           numChops - midChopIdx - 1, T, localT1);
        return;
    }

    this->appendCubics(mode, p0, p1, p2, p3);
}

void GrCCFillGeometry::appendCubics(AppendCubicMode mode, const Sk2f& p0, const Sk2f& p1,
                                    const Sk2f& p2, const Sk2f& p3, int maxSubdivisions) {
    if (SkCubicType::kLoop != fCurrCubicType) {
        // Serpentines and cusps are always monotonic after chopping around inflection points.
        SkASSERT(!SkCubicIsDegenerate(fCurrCubicType));

        if (AppendCubicMode::kApproximate == mode) {
            // This section passes through an inflection point, so we can get away with a flat line.
            // This can cause some curves to feel slightly more flat when inspected rigorously back
            // and forth against another renderer, but for now this seems acceptable given the
            // simplicity.
            this->appendLine(p0, p3);
            return;
        }
    } else {
        Sk2f tan0, tan1;
        get_cubic_tangents(p0, p1, p2, p3, &tan0, &tan1);

        if (maxSubdivisions && !is_convex_curve_monotonic(p0, tan0, p3, tan1)) {
            this->chopAndAppendCubicAtMidTangent(mode, p0, p1, p2, p3, tan0, tan1,
                                                 maxSubdivisions - 1);
            return;
        }

        if (AppendCubicMode::kApproximate == mode) {
            Sk2f c;
            if (!is_cubic_nearly_quadratic(p0, p1, p2, p3, tan0, tan1, &c) && maxSubdivisions) {
                this->chopAndAppendCubicAtMidTangent(mode, p0, p1, p2, p3, tan0, tan1,
                                                     maxSubdivisions - 1);
                return;
            }

            this->appendMonotonicQuadratic(p0, c, p3);
            return;
        }
    }

    // Don't send curves to the GPU if we know they are nearly flat (or just very small).
    // Since the cubic segment is known to be convex at this point, our flatness check is simple.
    if (are_collinear(p0, (p1 + p2) * .5f, p3)) {
        this->appendLine(p0, p3);
        return;
    }

    SkASSERT(fPoints.back() == SkPoint::Make(p0[0], p0[1]));
    SkASSERT((p0 != p3).anyTrue());
    p1.store(&fPoints.push_back());
    p2.store(&fPoints.push_back());
    p3.store(&fPoints.push_back());
    fVerbs.push_back(Verb::kMonotonicCubicTo);
    ++fCurrContourTallies.fCubics;
}

// Given a convex curve segment with the following order-2 tangent function:
//
//                                                       |C2x  C2y|
//     tan = some_scale * |dx/dt  dy/dt| = |t^2  t  1| * |C1x  C1y|
//                                                       |C0x  C0y|
//
// This function finds the T value whose tangent angle is halfway between the tangents at T=0 and
// T=1 (tan0 and tan1).
static inline float find_midtangent(const Sk2f& tan0, const Sk2f& tan1,
                                    const Sk2f& C2, const Sk2f& C1, const Sk2f& C0) {
    // Tangents point in the direction of increasing T, so tan0 and -tan1 both point toward the
    // midtangent. 'n' will therefore bisect tan0 and -tan1, giving us the normal to the midtangent.
    //
    //     n dot midtangent = 0
    //
    Sk2f n = normalize(tan0) - normalize(tan1);

    // Find the T value at the midtangent. This is a simple quadratic equation:
    //
    //     midtangent dot n = 0
    //
    //     (|t^2  t  1| * C) dot n = 0
    //
    //     |t^2  t  1| dot C*n = 0
    //
    // First find coeffs = C*n.
    Sk4f C[2];
    Sk2f::Store4(C, C2, C1, C0, 0);
    Sk4f coeffs = C[0]*n[0] + C[1]*n[1];

    // Now solve the quadratic.
    float a = coeffs[0], b = coeffs[1], c = coeffs[2];
    float discr = b*b - 4*a*c;
    if (discr < 0) {
        return 0; // This will only happen if the curve is a line.
    }

    // The roots are q/a and c/q. Pick the one closer to T=.5.
    float q = -.5f * (b + copysignf(std::sqrt(discr), b));
    float r = .5f*q*a;
    return std::abs(q*q - r) < std::abs(a*c - r) ? q/a : c/q;
}

inline void GrCCFillGeometry::chopAndAppendCubicAtMidTangent(AppendCubicMode mode, const Sk2f& p0,
                                                             const Sk2f& p1, const Sk2f& p2,
                                                             const Sk2f& p3, const Sk2f& tan0,
                                                             const Sk2f& tan1,
                                                             int maxFutureSubdivisions) {
    float midT = find_midtangent(tan0, tan1, p3 + (p1 - p2)*3 - p0,
                                             (p0 - p1*2 + p2)*2,
                                             p1 - p0);
    // Use positive logic since NaN fails comparisons. (However midT should not be NaN since we cull
    // near-flat cubics in cubicTo().)
    if (!(midT > 0 && midT < 1)) {
        // The cubic is flat. Otherwise there would be a real midtangent inside T=0..1.
        this->appendLine(p0, p3);
        return;
    }

    Sk2f p01, p02, pT, p11, p12;
    chop_cubic(p0, p1, p2, p3, midT, &p01, &p02, &pT, &p11, &p12);
    this->appendCubics(mode, p0, p01, p02, pT, maxFutureSubdivisions);
    this->appendCubics(mode, pT, p11, p12, p3, maxFutureSubdivisions);
}

void GrCCFillGeometry::conicTo(const SkPoint P[3], float w) {
    SkASSERT(fBuildingContour);
    SkASSERT(P[0] == fPoints.back());
    Sk2f p0 = Sk2f::Load(P);
    Sk2f p1 = Sk2f::Load(P+1);
    Sk2f p2 = Sk2f::Load(P+2);

    Sk2f tan0 = p1 - p0;
    Sk2f tan1 = p2 - p1;

    if (!is_convex_curve_monotonic(p0, tan0, p2, tan1)) {
        // The derivative of a conic has a cumbersome order-4 denominator. However, this isn't
        // necessary if we are only interested in a vector in the same *direction* as a given
        // tangent line. Since the denominator scales dx and dy uniformly, we can throw it out
        // completely after evaluating the derivative with the standard quotient rule. This leaves
        // us with a simpler quadratic function that we use to find the midtangent.
        float midT = find_midtangent(tan0, tan1, (w - 1) * (p2 - p0),
                                                 (p2 - p0) - 2*w*(p1 - p0),
                                                 w*(p1 - p0));
        // Use positive logic since NaN fails comparisons. (However midT should not be NaN since we
        // cull near-linear conics above. And while w=0 is flat, it's not a line and has valid
        // midtangents.)
        if (!(midT > 0 && midT < 1)) {
            // The conic is flat. Otherwise there would be a real midtangent inside T=0..1.
            this->appendLine(p0, p2);
            return;
        }

        // Chop the conic at midtangent to produce two monotonic segments.
        Sk4f p3d0 = Sk4f(p0[0], p0[1], 1, 0);
        Sk4f p3d1 = Sk4f(p1[0], p1[1], 1, 0) * w;
        Sk4f p3d2 = Sk4f(p2[0], p2[1], 1, 0);
        Sk4f midT4 = midT;

        Sk4f p3d01 = lerp(p3d0, p3d1, midT4);
        Sk4f p3d12 = lerp(p3d1, p3d2, midT4);
        Sk4f p3d012 = lerp(p3d01, p3d12, midT4);

        Sk2f midpoint = Sk2f(p3d012[0], p3d012[1]) / p3d012[2];
        Sk2f ww = Sk2f(p3d01[2], p3d12[2]) * Sk2f(p3d012[2]).rsqrt();

        this->appendMonotonicConic(p0, Sk2f(p3d01[0], p3d01[1]) / p3d01[2], midpoint, ww[0]);
        this->appendMonotonicConic(midpoint, Sk2f(p3d12[0], p3d12[1]) / p3d12[2], p2, ww[1]);
        return;
    }

    this->appendMonotonicConic(p0, p1, p2, w);
}

void GrCCFillGeometry::appendMonotonicConic(const Sk2f& p0, const Sk2f& p1, const Sk2f& p2,
                                            float w) {
    SkASSERT(w >= 0);

    Sk2f base = p2 - p0;
    Sk2f baseAbs = base.abs();
    float baseWidth = baseAbs[0] + baseAbs[1];

    // Find the height of the curve. Max height always occurs at T=.5 for conics.
    Sk2f d = (p1 - p0) * SkNx_shuffle<1,0>(base);
    float h1 = std::abs(d[1] - d[0]); // Height of p1 above the base.
    float ht = h1*w, hs = 1 + w; // Height of the conic = ht/hs.

    // i.e. (ht/hs <= baseWidth * kFlatnessThreshold). Use "<=" in case base == 0.
    if (ht <= (baseWidth*hs) * kFlatnessThreshold) {
        // We are flat. (See rationale in are_collinear.)
        this->appendLine(p0, p2);
        return;
    }

    // i.e. (w > 1 && h1 - ht/hs < baseWidth).
    if (w > 1 && h1*hs - ht < baseWidth*hs) {
        // If we get within 1px of p1 when w > 1, we will pick up artifacts from the implicit
        // function's reflection. Chop at max height (T=.5) and draw a triangle instead.
        Sk2f p1w = p1*w;
        Sk2f ab = p0 + p1w;
        Sk2f bc = p1w + p2;
        Sk2f highpoint = (ab + bc) / (2*(1 + w));
        this->appendLine(p0, highpoint);
        this->appendLine(highpoint, p2);
        return;
    }

    SkASSERT(fPoints.back() == SkPoint::Make(p0[0], p0[1]));
    SkASSERT((p0 != p2).anyTrue());
    p1.store(&fPoints.push_back());
    p2.store(&fPoints.push_back());
    fConicWeights.push_back(w);
    fVerbs.push_back(Verb::kMonotonicConicTo);
    ++fCurrContourTallies.fConics;
}

GrCCFillGeometry::PrimitiveTallies GrCCFillGeometry::endContour() {
    SkASSERT(fBuildingContour);
    SkASSERT(fVerbs.count() >= fCurrContourTallies.fTriangles);

    // The fTriangles field currently contains this contour's starting verb index. We can now
    // use it to calculate the size of the contour's fan.
    int fanSize = fVerbs.count() - fCurrContourTallies.fTriangles;
    if (fPoints.back() == fCurrAnchorPoint) {
        --fanSize;
        fVerbs.push_back(Verb::kEndClosedContour);
    } else {
        fVerbs.push_back(Verb::kEndOpenContour);
    }

    fCurrContourTallies.fTriangles = SkTMax(fanSize - 2, 0);

    SkDEBUGCODE(fBuildingContour = false);
    return fCurrContourTallies;
}
