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

#include "GrQuadPerEdgeAA.h"
#include "GrQuad.h"
#include "GrVertexWriter.h"
#include "glsl/GrGLSLColorSpaceXformHelper.h"
#include "glsl/GrGLSLGeometryProcessor.h"
#include "glsl/GrGLSLPrimitiveProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLVarying.h"
#include "glsl/GrGLSLVertexGeoBuilder.h"
#include "SkNx.h"

#define AI SK_ALWAYS_INLINE

namespace {

static AI Sk4f fma(const Sk4f& f, const Sk4f& m, const Sk4f& a) {
    return SkNx_fma<4, float>(f, m, a);
}

// These rotate the points/edge values either clockwise or counterclockwise assuming tri strip
// order.
static AI Sk4f nextCW(const Sk4f& v) {
    return SkNx_shuffle<2, 0, 3, 1>(v);
}

static AI Sk4f nextCCW(const Sk4f& v) {
    return SkNx_shuffle<1, 3, 0, 2>(v);
}

// Fills Sk4f with 1f if edge bit is set, 0f otherwise. Edges are ordered LBTR to match CCW ordering
// of vertices in the quad.
static AI Sk4f compute_edge_mask(GrQuadAAFlags aaFlags) {
    return Sk4f((GrQuadAAFlags::kLeft & aaFlags) ? 1.f : 0.f,
                (GrQuadAAFlags::kBottom & aaFlags) ? 1.f : 0.f,
                (GrQuadAAFlags::kTop & aaFlags) ? 1.f : 0.f,
                (GrQuadAAFlags::kRight & aaFlags) ? 1.f : 0.f);
}

// Outputs normalized edge vectors in xdiff and ydiff, as well as the reciprocal of the original
// edge lengths in invLengths
static AI void compute_edge_vectors(const Sk4f& x, const Sk4f& y, const Sk4f& xnext,
                                    const Sk4f& ynext, Sk4f* xdiff, Sk4f* ydiff, Sk4f* invLengths) {
    *xdiff = xnext - x;
    *ydiff = ynext - y;
    *invLengths = fma(*xdiff, *xdiff, *ydiff * *ydiff).rsqrt();
    *xdiff *= *invLengths;
    *ydiff *= *invLengths;
}

static AI void outset_masked_vertices(const Sk4f& xdiff, const Sk4f& ydiff, const Sk4f& invLengths,
                                      const Sk4f& mask, Sk4f* x, Sk4f* y, Sk4f* u, Sk4f* v, Sk4f* r,
                                      int uvrCount) {
    auto halfMask = 0.5f * mask;
    auto maskCW = nextCW(halfMask);
    *x += maskCW * -xdiff + halfMask * nextCW(xdiff);
    *y += maskCW * -ydiff + halfMask * nextCW(ydiff);
    if (uvrCount > 0) {
        // We want to extend the texture coords by the same proportion as the positions.
        maskCW *= invLengths;
        halfMask *= nextCW(invLengths);
        Sk4f udiff = nextCCW(*u) - *u;
        Sk4f vdiff = nextCCW(*v) - *v;
        *u += maskCW * -udiff + halfMask * nextCW(udiff);
        *v += maskCW * -vdiff + halfMask * nextCW(vdiff);
        if (uvrCount == 3) {
            Sk4f rdiff = nextCCW(*r) - *r;
            *r += maskCW * -rdiff + halfMask * nextCW(rdiff);
        }
    }
}

static AI void outset_vertices(const Sk4f& xdiff, const Sk4f& ydiff, const Sk4f& invLengths,
                               Sk4f* x, Sk4f* y, Sk4f* u, Sk4f* v, Sk4f* r, int uvrCount) {
    *x += 0.5f * (-xdiff + nextCW(xdiff));
    *y += 0.5f * (-ydiff + nextCW(ydiff));
    if (uvrCount > 0) {
        Sk4f t = 0.5f * invLengths;
        Sk4f udiff = nextCCW(*u) - *u;
        Sk4f vdiff = nextCCW(*v) - *v;
        *u += t * -udiff + nextCW(t) * nextCW(udiff);
        *v += t * -vdiff + nextCW(t) * nextCW(vdiff);
        if (uvrCount == 3) {
            Sk4f rdiff = nextCCW(*r) - *r;
            *r += t * -rdiff + nextCW(t) * nextCW(rdiff);
        }
    }
}

static AI void compute_edge_distances(const Sk4f& a, const Sk4f& b, const Sk4f& c, const Sk4f& x,
                                      const Sk4f& y, const Sk4f& w, Sk4f edgeDistances[]) {
    for (int i = 0; i < 4; ++i) {
        edgeDistances[i] = a * x[i] + b * y[i] + c * w[i];
    }
}

static AI float get_max_coverage(const Sk4f& lengths) {
    float minWidth = SkMinScalar(lengths[0], lengths[3]);
    float minHeight = SkMinScalar(lengths[1], lengths[2]);
    // Calculate approximate area of the quad, pinning dimensions to 1 in case the quad is larger
    // than a pixel. Sub-pixel quads that are rotated may in fact have a different true maximum
    // coverage than this calculation, but this will be close and is stable.
    return SkMinScalar(minWidth, 1.f) * SkMinScalar(minHeight, 1.f);
}

// This computes the four edge equations for a quad, then outsets them and optionally computes a new
// quad as the intersection points of the outset edges. 'x' and 'y' contain the original points as
// input and the outset points as output. In order to be used as a component of perspective edge
// distance calculation, this exports edge equations in 'a', 'b', and 'c'. Use
// compute_edge_distances to turn these equations into the distances needed by the shader. The
// values in x, y, u, v, and r are possibly updated if outsetting is needed. r is the local
// position's w component if it exists.
//
// Returns maximum coverage allowed for any given pixel.
static float compute_quad_edges_and_outset_vertices(GrQuadAAFlags aaFlags, Sk4f* x, Sk4f* y,
        Sk4f* a, Sk4f* b, Sk4f* c, Sk4f* u, Sk4f* v, Sk4f* r, int uvrChannelCount, bool outset) {
    SkASSERT(uvrChannelCount == 0 || uvrChannelCount == 2 || uvrChannelCount == 3);

    // Compute edge vectors for the quad.
    auto xnext = nextCCW(*x);
    auto ynext = nextCCW(*y);
    // xdiff and ydiff will comprise the normalized vectors pointing along each quad edge.
    Sk4f xdiff, ydiff, invLengths;
    compute_edge_vectors(*x, *y, xnext, ynext, &xdiff, &ydiff, &invLengths);

    // Use above vectors to compute edge equations (importantly before we outset positions).
    *c = fma(xnext, *y,  -ynext * *x) * invLengths;
    // Make sure the edge equations have their normals facing into the quad in device space.
    auto test = fma(ydiff, nextCW(*x), fma(-xdiff, nextCW(*y), *c));
    if ((test < Sk4f(0)).anyTrue()) {
        *a = -ydiff;
        *b = xdiff;
        *c = -*c;
    } else {
        *a = ydiff;
        *b = -xdiff;
    }
    // Outset the edge equations so aa coverage evaluates to zero half a pixel away from the
    // original quad edge.
    *c += 0.5f;

    if (aaFlags != GrQuadAAFlags::kAll) {
        // This order is the same order the edges appear in xdiff/ydiff and therefore as the
        // edges in a/b/c.
        Sk4f mask = compute_edge_mask(aaFlags);

        // Outset edge equations for masked out edges another pixel so that they always evaluate
        // >= 1.
        *c += (1.f - mask);
        if (outset) {
            outset_masked_vertices(xdiff, ydiff, invLengths, mask, x, y, u, v, r, uvrChannelCount);
        }
    } else if (outset) {
        outset_vertices(xdiff, ydiff, invLengths, x, y, u, v, r, uvrChannelCount);
    }

    return get_max_coverage(invLengths.invert());
}

// A specialization of the above function that can compute edge distances very quickly when it knows
// that the edges intersect at right angles, i.e. any transform other than skew and perspective
// (GrQuadType::kRectilinear). Unlike the above function, this always outsets the corners since it
// cannot be reused in the perspective case.
static float compute_rectilinear_dists_and_outset_vertices(GrQuadAAFlags aaFlags, Sk4f* x,
        Sk4f* y,  Sk4f edgeDistances[4], Sk4f* u, Sk4f* v, Sk4f* r, int uvrChannelCount) {
    SkASSERT(uvrChannelCount == 0 || uvrChannelCount == 2 || uvrChannelCount == 3);
    // xdiff and ydiff will comprise the normalized vectors pointing along each quad edge.
    Sk4f xdiff, ydiff, invLengths;
    compute_edge_vectors(*x, *y, nextCCW(*x), nextCCW(*y), &xdiff, &ydiff, &invLengths);
    Sk4f lengths = invLengths.invert();

    // Since the quad is rectilinear, the edge distances are predictable and independent of the
    // actual orientation of the quad. The lengths vector stores |p1-p0|, |p3-p1|, |p0-p2|, |p2-p3|,
    // matching the CCW order. For instance, edge distances for p0 are 0 for e0 and e2 since they
    // intersect at p0. Distance to e1 is the same as p0 to p1. Distance to e3 is p0 to p2 since
    // e3 goes through p2 and since the quad is rectilinear, we know that's the shortest distance.
    edgeDistances[0] = Sk4f(0.f, lengths[0], 0.f, lengths[2]);
    edgeDistances[1] = Sk4f(0.f, 0.f, lengths[0], lengths[1]);
    edgeDistances[2] = Sk4f(lengths[2], lengths[3], 0.f, 0.f);
    edgeDistances[3] = Sk4f(lengths[1], 0.f, lengths[3], 0.f);

    if (aaFlags != GrQuadAAFlags::kAll) {
        // This order is the same order the edges appear in xdiff/ydiff and therefore as the
        // edges in a/b/c.
        Sk4f mask = compute_edge_mask(aaFlags);

        // Update opposite corner distances by 1 (when enabled by the mask). The distance
        // calculations used in compute_quad_edges_... calculates the edge equations from original
        // positions and then shifts the coefficient by 0.5. If the opposite edges are also outset
        // then must add an additional 0.5 to account for its shift away from that edge.
        Sk4f maskWithOpposites = mask + SkNx_shuffle<3, 2, 1, 0>(mask);
        edgeDistances[0] += Sk4f(0.f, 0.5f, 0.f, 0.5f) * maskWithOpposites;
        edgeDistances[1] += Sk4f(0.f, 0.f, 0.5f, 0.5f) * maskWithOpposites;
        edgeDistances[2] += Sk4f(0.5f, 0.5f, 0.f, 0.f) * maskWithOpposites;
        edgeDistances[3] += Sk4f(0.5f, 0.f, 0.5f, 0.f) * maskWithOpposites;

        // Outset edge equations for masked out edges another pixel so that they always evaluate
        // So add 1-mask to each point's edge distances vector so that coverage >= 1 on non-aa
        for (int i = 0; i < 4; ++i) {
            edgeDistances[i] += (1.f - mask);
        }
        outset_masked_vertices(xdiff, ydiff, invLengths, mask, x, y, u, v, r, uvrChannelCount);
    } else {
        // Update opposite corner distances by 0.5 pixel and 0.5 edge shift, skipping the need for
        // mask since that's 1s
        edgeDistances[0] += Sk4f(0.f, 1.f, 0.f, 1.f);
        edgeDistances[1] += Sk4f(0.f, 0.f, 1.f, 1.f);
        edgeDistances[2] += Sk4f(1.f, 1.f, 0.f, 0.f);
        edgeDistances[3] += Sk4f(1.f, 0.f, 1.f, 0.f);

        outset_vertices(xdiff, ydiff, invLengths, x, y, u, v, r, uvrChannelCount);
    }

    return get_max_coverage(lengths);
}

// Generalizes compute_quad_edge_distances_and_outset_vertices to extrapolate local coords such that
// after perspective division of the device coordinate, the original local coordinate value is at
// the original un-outset device position. r is the local coordinate's w component.
static float compute_quad_dists_and_outset_persp_vertices(GrQuadAAFlags aaFlags, Sk4f* x,
        Sk4f* y, Sk4f* w, Sk4f edgeDistances[4], Sk4f* u, Sk4f* v, Sk4f* r, int uvrChannelCount) {
    SkASSERT(uvrChannelCount == 0 || uvrChannelCount == 2 || uvrChannelCount == 3);

    auto iw = (*w).invert();
    auto x2d = (*x) * iw;
    auto y2d = (*y) * iw;
    Sk4f a, b, c;
    // Don't compute outset corners in the normalized space, which means u, v, and r don't need
    // to be provided here (outset separately below). Since this is computing distances for a
    // projected quad, there is a very good chance it's not rectilinear so use the general 2D path.
    float maxProjectedCoverage = compute_quad_edges_and_outset_vertices(aaFlags, &x2d, &y2d,
            &a, &b, &c, nullptr, nullptr, nullptr, /* uvr ct */ 0, /* outsetCorners */ false);

    static const float kOutset = 0.5f;
    if ((GrQuadAAFlags::kLeft | GrQuadAAFlags::kRight) & aaFlags) {
        // For each entry in x the equivalent entry in opX is the left/right opposite and so on.
        Sk4f opX = SkNx_shuffle<2, 3, 0, 1>(*x);
        Sk4f opW = SkNx_shuffle<2, 3, 0, 1>(*w);
        Sk4f opY = SkNx_shuffle<2, 3, 0, 1>(*y);
        // vx/vy holds the device space left-to-right vectors along top and bottom of the quad.
        Sk2f vx = SkNx_shuffle<2, 3>(x2d) - SkNx_shuffle<0, 1>(x2d);
        Sk2f vy = SkNx_shuffle<2, 3>(y2d) - SkNx_shuffle<0, 1>(y2d);
        Sk2f len = SkNx_fma(vx, vx, vy * vy).sqrt();
        // For each device space corner, devP, label its left/right opposite device space point
        // opDevPt. The new device space point is opDevPt + s (devPt - opDevPt) where s is
        // (length(devPt - opDevPt) + 0.5) / length(devPt - opDevPt);
        Sk4f s = SkNx_shuffle<0, 1, 0, 1>((len + kOutset) / len);
        // Compute t in homogeneous space from s using similar triangles so that we can produce
        // homogeneous outset vertices for perspective-correct interpolation.
        Sk4f sOpW = s * opW;
        Sk4f t = sOpW / (sOpW + (1.f - s) * (*w));
        // mask is used to make the t values be 1 when the left/right side is not antialiased.
        Sk4f mask(GrQuadAAFlags::kLeft & aaFlags  ? 1.f : 0.f,
                  GrQuadAAFlags::kLeft & aaFlags  ? 1.f : 0.f,
                  GrQuadAAFlags::kRight & aaFlags ? 1.f : 0.f,
                  GrQuadAAFlags::kRight & aaFlags ? 1.f : 0.f);
        t = t * mask + (1.f - mask);
        *x = opX + t * (*x - opX);
        *y = opY + t * (*y - opY);
        *w = opW + t * (*w - opW);

        if (uvrChannelCount > 0) {
            Sk4f opU = SkNx_shuffle<2, 3, 0, 1>(*u);
            Sk4f opV = SkNx_shuffle<2, 3, 0, 1>(*v);
            *u = opU + t * (*u - opU);
            *v = opV + t * (*v - opV);
            if (uvrChannelCount == 3) {
                Sk4f opR = SkNx_shuffle<2, 3, 0, 1>(*r);
                *r = opR + t * (*r - opR);
            }
        }

        if ((GrQuadAAFlags::kTop | GrQuadAAFlags::kBottom) & aaFlags) {
            // Update the 2D points for the top/bottom calculation.
            iw = (*w).invert();
            x2d = (*x) * iw;
            y2d = (*y) * iw;
        }
    }

    if ((GrQuadAAFlags::kTop | GrQuadAAFlags::kBottom) & aaFlags) {
        // This operates the same as above but for top/bottom rather than left/right.
        Sk4f opX = SkNx_shuffle<1, 0, 3, 2>(*x);
        Sk4f opW = SkNx_shuffle<1, 0, 3, 2>(*w);
        Sk4f opY = SkNx_shuffle<1, 0, 3, 2>(*y);

        Sk2f vx = SkNx_shuffle<1, 3>(x2d) - SkNx_shuffle<0, 2>(x2d);
        Sk2f vy = SkNx_shuffle<1, 3>(y2d) - SkNx_shuffle<0, 2>(y2d);
        Sk2f len = SkNx_fma(vx, vx, vy * vy).sqrt();

        Sk4f s = SkNx_shuffle<0, 0, 1, 1>((len + kOutset) / len);

        Sk4f sOpW = s * opW;
        Sk4f t = sOpW / (sOpW + (1.f - s) * (*w));

        Sk4f mask(GrQuadAAFlags::kTop    & aaFlags ? 1.f : 0.f,
                  GrQuadAAFlags::kBottom & aaFlags ? 1.f : 0.f,
                  GrQuadAAFlags::kTop    & aaFlags ? 1.f : 0.f,
                  GrQuadAAFlags::kBottom & aaFlags ? 1.f : 0.f);
        t = t * mask + (1.f - mask);
        *x = opX + t * (*x - opX);
        *y = opY + t * (*y - opY);
        *w = opW + t * (*w - opW);

        if (uvrChannelCount > 0) {
            Sk4f opU = SkNx_shuffle<1, 0, 3, 2>(*u);
            Sk4f opV = SkNx_shuffle<1, 0, 3, 2>(*v);
            *u = opU + t * (*u - opU);
            *v = opV + t * (*v - opV);
            if (uvrChannelCount == 3) {
                Sk4f opR = SkNx_shuffle<1, 0, 3, 2>(*r);
                *r = opR + t * (*r - opR);
            }
        }
    }

    // Use the original edge equations with the outset homogeneous coordinates to get the edge
    // distance (technically multiplied by w, so that the fragment shader can do perspective
    // interpolation when it multiplies by 1/w later).
    compute_edge_distances(a, b, c, *x, *y, *w, edgeDistances);

    return maxProjectedCoverage;
}

// Calculate safe edge distances for non-aa quads that have been batched with aa quads. Since the
// fragment shader multiples by 1/w, so the edge distance cannot just be set to 1. It cannot just
// be set to w either due to interpolation across the triangle. If iA, iB, and iC are the
// barycentric weights of the triangle, and we set the edge distance to w, the fragment shader
// actually sees d = (iA*wA + iB*wB + iC*wC) * (iA/wA + iB/wB + iC/wC). Without perspective this
// simplifies to 1 as necessary, but we must choose something other than w when there is perspective
// to ensure that d >= 1 and the edge shows as non-aa.
static float compute_nonaa_edge_distances(const Sk4f& w, bool hasPersp, Sk4f edgeDistances[4]) {
    // Let n = min(w1,w2,w3,w4) and m = max(w1,w2,w3,w4) and rewrite
    //   d = (iA*wA + iB*wB + iC*wC) * (iA*wB*wC + iB*wA*wC + iC*wA*wB) / (wA*wB*wC)
    //       |   e=attr from VS    |   |         fragCoord.w = 1/w                 |
    // Since the weights are the interior of the primitive then we have:
    //   n <= (iA*wA + iB*wB + iC*wC) <= m and
    //   n^2 <= (iA*wB*wC + iB*wA*wC + iC*wA*wB) <= m^2 and
    //   n^3 <= wA*wB*wC <= m^3 regardless of the choice of A, B, and C verts in the quad
    // Thus if we set e = m^3/n^3, it guarantees d >= 1 for any perspective.
    float e;
    if (hasPersp) {
        float m = w.max();
        float n = w.min();
        e = (m * m * m) / (n * n * n);
    } else {
        e = 1.f;
    }

    // All edge distances set to the same
    for (int i = 0; i < 4; ++i) {
        edgeDistances[i] = e;
    }

    // Non-aa, so always use full coverage
    return 1.f;
}

} // anonymous namespace

namespace GrQuadPerEdgeAA {

////////////////// Tessellate Implementation

void* Tessellate(void* vertices, const VertexSpec& spec, const GrPerspQuad& deviceQuad,
                 const SkPMColor4f& color4f, const GrPerspQuad& localQuad, const SkRect& domain,
                 GrQuadAAFlags aaFlags) {
    bool deviceHasPerspective = spec.deviceQuadType() == GrQuadType::kPerspective;
    bool localHasPerspective = spec.localQuadType() == GrQuadType::kPerspective;
    GrVertexColor color(color4f, GrQuadPerEdgeAA::ColorType::kHalf == spec.colorType());

    // Load position data into Sk4fs (always x, y, and load w to avoid branching down the road)
    Sk4f x = deviceQuad.x4f();
    Sk4f y = deviceQuad.y4f();
    Sk4f w = deviceQuad.w4f(); // Guaranteed to be 1f if it's not perspective

    // Load local position data into Sk4fs (either none, just u,v or all three)
    Sk4f u, v, r;
    if (spec.hasLocalCoords()) {
        u = localQuad.x4f();
        v = localQuad.y4f();

        if (localHasPerspective) {
            r = localQuad.w4f();
        }
    }

    // Index into array refers to vertex. Index into particular Sk4f refers to edge.
    Sk4f edgeDistances[4];
    float maxCoverage = 1.f;
    if (spec.usesCoverageAA()) {
        // Must calculate edges and possibly outside the positions
        if (aaFlags == GrQuadAAFlags::kNone) {
            // A non-AA quad that got batched into an AA group, so it should have full coverage
            maxCoverage = compute_nonaa_edge_distances(w, deviceHasPerspective, edgeDistances);
        } else if (deviceHasPerspective) {
            // For simplicity, pointers to u, v, and r are always provided, but the local dim param
            // ensures that only loaded Sk4fs are modified in the compute functions.
            maxCoverage = compute_quad_dists_and_outset_persp_vertices(aaFlags, &x, &y, &w,
                    edgeDistances, &u, &v, &r, spec.localDimensionality());
        } else if (spec.deviceQuadType() <= GrQuadType::kRectilinear) {
            maxCoverage = compute_rectilinear_dists_and_outset_vertices(aaFlags, &x, &y,
                    edgeDistances, &u, &v, &r, spec.localDimensionality());
        } else {
            Sk4f a, b, c;
            maxCoverage = compute_quad_edges_and_outset_vertices(aaFlags, &x, &y, &a, &b, &c,
                    &u, &v, &r, spec.localDimensionality(), /*outset*/ true);
            compute_edge_distances(a, b, c, x, y, w, edgeDistances); // w holds 1.f as desired
        }
    }

    // Now rearrange the Sk4fs into the interleaved vertex layout:
    //  i.e. x1x2x3x4 y1y2y3y4 -> x1y1 x2y2 x3y3 x4y
    GrVertexWriter vb{vertices};
    for (int i = 0; i < 4; ++i) {
        // save position, always send a vec4 because we embed max coverage in the last component.
        // For 2D quads, we know w holds the correct 1.f, so just write it out without branching
        vb.write(x[i], y[i], w[i], maxCoverage);

        // save color
        if (spec.hasVertexColors()) {
            vb.write(color);
        }

        // save local position
        if (spec.hasLocalCoords()) {
            if (localHasPerspective) {
                vb.write<SkPoint3>({u[i], v[i], r[i]});
            } else {
                vb.write<SkPoint>({u[i], v[i]});
            }
        }

        // save the domain
        if (spec.hasDomain()) {
            vb.write(domain);
        }

        // save the edges
        if (spec.usesCoverageAA()) {
            vb.write(edgeDistances[i]);
        }
    }

    return vb.fPtr;
}

////////////////// VertexSpec Implementation

int VertexSpec::deviceDimensionality() const {
    return this->deviceQuadType() == GrQuadType::kPerspective ? 3 : 2;
}

int VertexSpec::localDimensionality() const {
    return fHasLocalCoords ? (this->localQuadType() == GrQuadType::kPerspective ? 3 : 2) : 0;
}

////////////////// Geometry Processor Implementation

class QuadPerEdgeAAGeometryProcessor : public GrGeometryProcessor {
public:

    static sk_sp<GrGeometryProcessor> Make(const VertexSpec& spec) {
        return sk_sp<QuadPerEdgeAAGeometryProcessor>(new QuadPerEdgeAAGeometryProcessor(spec));
    }

    static sk_sp<GrGeometryProcessor> Make(const VertexSpec& vertexSpec, const GrShaderCaps& caps,
                                           GrTextureType textureType, GrPixelConfig textureConfig,
                                           const GrSamplerState& samplerState,
                                           uint32_t extraSamplerKey,
                                           sk_sp<GrColorSpaceXform> textureColorSpaceXform) {
        return sk_sp<QuadPerEdgeAAGeometryProcessor>(new QuadPerEdgeAAGeometryProcessor(
                vertexSpec, caps, textureType, textureConfig, samplerState, extraSamplerKey,
                std::move(textureColorSpaceXform)));
    }

    const char* name() const override { return "QuadPerEdgeAAGeometryProcessor"; }

    void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
        // aa, domain, texturing are single bit flags
        uint32_t x = fAAEdgeDistances.isInitialized() ? 0 : 1;
        x |= fDomain.isInitialized() ? 0 : 2;
        x |= fSampler.isInitialized() ? 0 : 4;
        // regular position has two options as well
        x |= fNeedsPerspective ? 0 : 8;
        // local coords require 2 bits (3 choices), 00 for none, 01 for 2d, 10 for 3d
        if (fLocalCoord.isInitialized()) {
            x |= kFloat3_GrVertexAttribType == fLocalCoord.cpuType() ? 16 : 32;
        }
        // similar for colors, 00 for none, 01 for bytes, 10 for half-floats
        if (this->fColor.isInitialized()) {
            x |= kUByte4_norm_GrVertexAttribType == fColor.cpuType() ? 64 : 128;
        }

        b->add32(GrColorSpaceXform::XformKey(fTextureColorSpaceXform.get()));
        b->add32(x);
    }

    GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps& caps) const override {
        class GLSLProcessor : public GrGLSLGeometryProcessor {
        public:
            void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc,
                         FPCoordTransformIter&& transformIter) override {
                const auto& gp = proc.cast<QuadPerEdgeAAGeometryProcessor>();
                if (gp.fLocalCoord.isInitialized()) {
                    this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
                }
                fTextureColorSpaceXformHelper.setData(pdman, gp.fTextureColorSpaceXform.get());
            }

        private:
            void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
                using Interpolation = GrGLSLVaryingHandler::Interpolation;

                const auto& gp = args.fGP.cast<QuadPerEdgeAAGeometryProcessor>();
                fTextureColorSpaceXformHelper.emitCode(args.fUniformHandler,
                                                       gp.fTextureColorSpaceXform.get());

                args.fVaryingHandler->emitAttributes(gp);

                // Extract effective position out of vec4 as a local variable in the vertex shader
                if (gp.fNeedsPerspective) {
                    args.fVertBuilder->codeAppendf("float3 position = %s.xyz;",
                                                   gp.fPositionWithCoverage.name());
                } else {
                    args.fVertBuilder->codeAppendf("float2 position = %s.xy;",
                                                   gp.fPositionWithCoverage.name());
                }
                gpArgs->fPositionVar = {"position",
                                        gp.fNeedsPerspective ? kFloat3_GrSLType : kFloat2_GrSLType,
                                        GrShaderVar::kNone_TypeModifier};

                // Handle local coordinates if they exist
                if (gp.fLocalCoord.isInitialized()) {
                    // NOTE: If the only usage of local coordinates is for the inline texture fetch
                    // before FPs, then there are no registered FPCoordTransforms and this ends up
                    // emitting nothing, so there isn't a duplication of local coordinates
                    this->emitTransforms(args.fVertBuilder,
                                         args.fVaryingHandler,
                                         args.fUniformHandler,
                                         gp.fLocalCoord.asShaderVar(),
                                         args.fFPCoordTransformHandler);
                }

                // Solid color before any texturing gets modulated in
                if (gp.fColor.isInitialized()) {
                    args.fVaryingHandler->addPassThroughAttribute(gp.fColor, args.fOutputColor,
                                                                  Interpolation::kCanBeFlat);
                }

                // If there is a texture, must also handle texture coordinates and reading from
                // the texture in the fragment shader before continuing to fragment processors.
                if (gp.fSampler.isInitialized()) {
                    // Texture coordinates clamped by the domain on the fragment shader; if the GP
                    // has a texture, it's guaranteed to have local coordinates
                    args.fFragBuilder->codeAppend("float2 texCoord;");
                    if (gp.fLocalCoord.cpuType() == kFloat3_GrVertexAttribType) {
                        // Can't do a pass through since we need to perform perspective division
                        GrGLSLVarying v(gp.fLocalCoord.gpuType());
                        args.fVaryingHandler->addVarying(gp.fLocalCoord.name(), &v);
                        args.fVertBuilder->codeAppendf("%s = %s;",
                                                       v.vsOut(), gp.fLocalCoord.name());
                        args.fFragBuilder->codeAppendf("texCoord = %s.xy / %s.z;",
                                                       v.fsIn(), v.fsIn());
                    } else {
                        args.fVaryingHandler->addPassThroughAttribute(gp.fLocalCoord, "texCoord");
                    }

                    // Clamp the now 2D localCoordName variable by the domain if it is provided
                    if (gp.fDomain.isInitialized()) {
                        args.fFragBuilder->codeAppend("float4 domain;");
                        args.fVaryingHandler->addPassThroughAttribute(gp.fDomain, "domain",
                                                                      Interpolation::kCanBeFlat);
                        args.fFragBuilder->codeAppend(
                                "texCoord = clamp(texCoord, domain.xy, domain.zw);");
                    }

                    // Now modulate the starting output color by the texture lookup
                    args.fFragBuilder->codeAppendf("%s = ", args.fOutputColor);
                    args.fFragBuilder->appendTextureLookupAndModulate(
                        args.fOutputColor, args.fTexSamplers[0], "texCoord", kFloat2_GrSLType,
                        &fTextureColorSpaceXformHelper);
                    args.fFragBuilder->codeAppend(";");
                }

                // And lastly, output the coverage calculation code
                if (gp.fAAEdgeDistances.isInitialized()) {
                    GrGLSLVarying maxCoverage(kFloat_GrSLType);
                    args.fVaryingHandler->addVarying("maxCoverage", &maxCoverage);
                    args.fVertBuilder->codeAppendf("%s = %s.w;",
                                                   maxCoverage.vsOut(), gp.fPositionWithCoverage.name());

                    args.fFragBuilder->codeAppend("float4 edgeDists;");
                    args.fVaryingHandler->addPassThroughAttribute(gp.fAAEdgeDistances, "edgeDists");

                    args.fFragBuilder->codeAppend(
                            "float minDist = min(min(edgeDists.x, edgeDists.y),"
                            " min(edgeDists.z, edgeDists.w));");
                    if (gp.fNeedsPerspective) {
                        // The distance from edge equation e to homogeneous point p=sk_Position is
                        // e.x*p.x/p.w + e.y*p.y/p.w + e.z. However, we want screen space
                        // interpolation of this distance. We can do this by multiplying the vertex
                        // attribute by p.w and then multiplying by sk_FragCoord.w in the FS. So we
                        // output e.x*p.x + e.y*p.y + e.z * p.w
                        args.fFragBuilder->codeAppend("minDist *= sk_FragCoord.w;");
                    }
                    // Clamp to max coverage after the perspective divide since perspective quads
                    // calculated the max coverage in projected space.
                    args.fFragBuilder->codeAppendf("%s = float4(clamp(minDist, 0.0, %s));",
                                                   args.fOutputCoverage, maxCoverage.fsIn());
                } else {
                    // Set coverage to 1
                    args.fFragBuilder->codeAppendf("%s = float4(1);", args.fOutputCoverage);
                }
            }
            GrGLSLColorSpaceXformHelper fTextureColorSpaceXformHelper;
        };
        return new GLSLProcessor;
    }

private:
    QuadPerEdgeAAGeometryProcessor(const VertexSpec& spec)
            : INHERITED(kQuadPerEdgeAAGeometryProcessor_ClassID)
            , fTextureColorSpaceXform(nullptr) {
        SkASSERT(spec.hasVertexColors() && !spec.hasDomain());
        this->initializeAttrs(spec);
        this->setTextureSamplerCnt(0);
    }

    QuadPerEdgeAAGeometryProcessor(const VertexSpec& spec, const GrShaderCaps& caps,
                                   GrTextureType textureType, GrPixelConfig textureConfig,
                                   const GrSamplerState& samplerState,
                                   uint32_t extraSamplerKey,
                                   sk_sp<GrColorSpaceXform> textureColorSpaceXform)
            : INHERITED(kQuadPerEdgeAAGeometryProcessor_ClassID)
            , fTextureColorSpaceXform(std::move(textureColorSpaceXform))
            , fSampler(textureType, textureConfig, samplerState, extraSamplerKey) {
        SkASSERT(spec.hasVertexColors() && spec.hasLocalCoords());
        this->initializeAttrs(spec);
        this->setTextureSamplerCnt(1);
    }

    void initializeAttrs(const VertexSpec& spec) {
        fNeedsPerspective = spec.deviceDimensionality() == 3;
        fPositionWithCoverage = {"posAndCoverage", kFloat4_GrVertexAttribType, kFloat4_GrSLType};

        int localDim = spec.localDimensionality();
        if (localDim == 3) {
            fLocalCoord = {"localCoord", kFloat3_GrVertexAttribType, kFloat3_GrSLType};
        } else if (localDim == 2) {
            fLocalCoord = {"localCoord", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
        } // else localDim == 0 and attribute remains uninitialized

        if (ColorType::kByte == spec.colorType()) {
            fColor = {"color", kUByte4_norm_GrVertexAttribType, kHalf4_GrSLType};
        } else if (ColorType::kHalf == spec.colorType()) {
            fColor = {"color", kHalf4_GrVertexAttribType, kHalf4_GrSLType};
        }

        if (spec.hasDomain()) {
            fDomain = {"domain", kFloat4_GrVertexAttribType, kFloat4_GrSLType};
        }

        if (spec.usesCoverageAA()) {
            fAAEdgeDistances = {"aaEdgeDist", kFloat4_GrVertexAttribType, kFloat4_GrSLType};
        }
        this->setVertexAttributes(&fPositionWithCoverage, 5);
    }

    const TextureSampler& onTextureSampler(int) const override { return fSampler; }

    Attribute fPositionWithCoverage;
    Attribute fColor;
    Attribute fLocalCoord;
    Attribute fDomain;
    Attribute fAAEdgeDistances;

    // The positions attribute is always a vec4 and can't be used to encode perspectiveness
    bool fNeedsPerspective;

    // Color space will be null and fSampler.isInitialized() returns false when the GP is configured
    // to skip texturing.
    sk_sp<GrColorSpaceXform> fTextureColorSpaceXform;
    TextureSampler fSampler;

    typedef GrGeometryProcessor INHERITED;
};

sk_sp<GrGeometryProcessor> MakeProcessor(const VertexSpec& spec) {
    return QuadPerEdgeAAGeometryProcessor::Make(spec);
}

sk_sp<GrGeometryProcessor> MakeTexturedProcessor(const VertexSpec& spec, const GrShaderCaps& caps,
        GrTextureType textureType, GrPixelConfig textureConfig,
        const GrSamplerState& samplerState, uint32_t extraSamplerKey,
        sk_sp<GrColorSpaceXform> textureColorSpaceXform) {
    return QuadPerEdgeAAGeometryProcessor::Make(spec, caps, textureType, textureConfig,
                                                samplerState, extraSamplerKey,
                                                std::move(textureColorSpaceXform));
}

} // namespace GrQuadPerEdgeAA
