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

#include "src/gpu/graphite/render/AnalyticRRectRenderStep.h"

#include "src/base/SkVx.h"
#include "src/core/SkRRectPriv.h"
#include "src/gpu/graphite/DrawParams.h"
#include "src/gpu/graphite/DrawWriter.h"
#include "src/gpu/graphite/render/CommonDepthStencilSettings.h"

// This RenderStep is flexible and can draw filled rectangles, filled quadrilaterals with per-edge
// AA, filled rounded rectangles with arbitrary corner radii, stroked rectangles with any join,
// and stroked rounded rectangles with circular corners (each corner can be different or square).
// We combine all of these together to maximize batching across simple geometric draws and reduce
// the number pipeline specializations. Additionally, these primitives are the most common
// operations and help us avoid triggering MSAA.
//
// Each of these "primitives" is represented by a single instance. The instance attributes are
// flexible enough to describe any of the above shapes without relying on uniforms to define its
// operation. The attributes encode shape as follows:
//
// float4 xRadiiOrFlags - if any components is > 0, the instance represents a filled round rect
//    with elliptical corners and these values specify the X radii in top-left CW order.
//    Otherwise, if .x < -1, the instance represents a stroked or hairline [round] rect, where .y
//    differentiates hairline vs. stroke. If .y is negative, then it is a hairline and xRadiiOrFlags
//    stores (-2 - X radii); otherwise it is a regular stroke and .z holds the stroke radius and
//    .w stores the join limit (matching StrokeStyle's conventions).
//    Else it's a filled quadrilateral with per-edge AA defined by each component: aa != 0.
// float4 radiiOrQuadXs - if in filled round rect or hairline [round] rect mode, these values
//    provide the Y radii in top-left CW order. If in stroked [round] rect mode, these values
//    provide the circular corner radii (same order). Otherwise, when in per-edge quad mode, these
//    values provide the X coordinates of the quadrilateral (same order).
// float4 ltrbOrQuadYs - if in filled round rect mode or stroked [round] rect mode, these values
//    define the LTRB edge coordinates of the rectangle surrounding the round rect (or the
//    rect itself when the radii are 0s). Otherwise, in per-edge quad mode, these values provide
//    the Y coordinates of the quadrilateral.
//
// From the other direction, shapes produce instance values like:
//  - filled rect:    [-1 -1 -1 -1]            [L R R L]             [T T B B]
//  - stroked rect:   [-2 0 stroke join]       [0 0 0 0]             [L T R B]
//  - hairline rect:  [-2 -2 -2 -2]            [0 0 0 0]             [L T R B]
//  - filled rrect:   [xRadii(tl,tr,br,bl)]    [yRadii(tl,tr,br,bl)] [L T R B]
//  - stroked rrect:  [-2 0 stroke join]       [radii(tl,tr,br,bl)]  [L T R B]
//  - hairline rrect: [-2-xRadii(tl,tr,br,bl)] [radii(tl,tr,br,bl)]  [L T R B]
//  - per-edge quad:  [aa(t,r,b,l) ? -1 : 0]   [xs(tl,tr,br,bl)]     [ys(tl,tr,br,bl)]
//
// This encoding relies on the fact that a valid SkRRect with all x radii equal to 0 must have
// y radii equal to 0 (so it's a rectangle and we can treat it as a quadrilateral with
// all edges AA'ed). This avoids other encodings' inability to represent a quad with all edges
// anti-aliased (e.g. checking for negatives in xRadiiOrFlags to turn on per-edge mode).
//
// From this encoding, data can be unpacked for each corner, which are equivalent under
// rotational symmetry. A corner can have an outer curve, be mitered, or be beveled. It can
// have an inner curve, an inner miter, or fill the interior. Per-edge quads are always mitered
// and fill the interior, but the vertices are placed such that the edge coverage ramps can
// collapse to 0 area on non-AA edges.
//
// The vertices that describe each corner are placed so that edges, miters, and bevels calculate
// coverage by interpolating a varying and then clamping in the fragment shader. Triangles that
// cover the inner and outer curves calculate distance to the curve within the fragment shader.
//
// See https://docs.google.com/presentation/d/1MCPstNsSlDBhR8CrsJo0r-cZNbu-sEJEvU9W94GOJoY/edit?usp=sharing
// for diagrams and explanation of how the geometry is defined.
//
// AnalyticRRectRenderStep uses the common technique of approximating distance to the level set by
// one expansion of the Taylor's series for the level set's equation. Given a level set function
// C(x,y), this amounts to calculating C(px,py)/|∇C(px,py)|. For the straight edges the level set
// is linear and calculated in the vertex shader and then interpolated exactly over the rectangle.
// This provides distances to all four exterior edges within the fragment shader and allows it to
// reconstruct a relative position per elliptical corner. Unfortunately this requires the fragment
// shader to calculate the length of the gradient for straight edges instead of interpolating
// exact device-space distance.
//
// All four corner radii are potentially evaluated by the fragment shader although each corner's
// coverage is only calculated when the pixel is within the bounding box of its quadrant. For fills
// and simple strokes it's theoretically valid to have each pixel calculate a single corner's
// coverage that was controlled via the vertex shader. However, testing all four corners is
// necessary in order to correctly handle self-intersecting stroke interiors. Similarly, all four
// edges must be evaluated in order to handle extremely thin shapes; whereas often you could get
// away with tracking a single edge distance per pixel.
//
// Analytic derivatives are used so that a single pipeline can be used regardless of HW derivative
// support or for geometry that would prove difficult for forward differencing. The device-space
// gradient for ellipses is calculated per-pixel by transforming a per-pixel local gradient vector
// with the Jacobian of the inverse local-to-device transform:
//
// (px,py) is the projected point of (u,v) transformed by a 3x3 matrix, M:
//                [x(u,v) / w(u,v)]       [x]   [m00 m01 m02] [u]
//      (px,py) = [y(u,v) / w(u,v)] where [y] = [m10 m11 m12]X[v] = M*(u,v,1)
//                                        [w]   [m20 m21 m22] [1]
//
// C(px,py) can be defined in terms of a local Cl(u,v) as C(px,py) = Cl(p^-1(px,py)), where p^-1 =
//
//               [x'(px,py) / w'(px,py)]       [x']   [m00' m01' * m02'] [px]
//      (u,v) =  [y'(px,py) / w'(px,py)] where [y'] = [m10' m11' * m12']X[py] = M^-1*(px,py,0,1)
//                                             [w']   [m20' m21' * m22'] [ 1]
//
// Note that if the 3x3 M was arrived by dropping the 3rd row and column from a 4x4 since we assume
// a local 3rd coordinate of 0, M^-1 is not equal to the 4x4 inverse with dropped rows and columns.
//
// Using the chain rule, then ∇C(px,py)
//   =  ∇Cl(u,v)X[1/w'(px,py)     0       -x'(px,py)/w'(px,py)^2] [m00' m01']
//               [    0       1/w'(px,py) -y'(px,py)/w'(px,py)^2]X[m10' m11']
//                                                                [m20' m21']
//
//   = 1/w'(px,py)*∇Cl(u,v)X[1 0 -x'(px,py)/w'(px,py)] [m00' m01']
//                          [0 1 -y'(px,py)/w'(px,py)]X[m10' m11']
//                                                     [m20' m21']
//
//   = w(u,v)*∇Cl(u,v)X[1 0 0 -u] [m00' m01']
//                     [0 1 0 -v]X[m10' m11']
//                                [m20' m21']
//
//   = w(u,v)*∇Cl(u,v)X[m00'-m20'u m01'-m21'u]
//                     [m10'-m20'v m11'-m21'v]
//
// The vertex shader calculates the rightmost 2x2 matrix and interpolates it across the shape since
// each component is linear in (u,v). ∇Cl(u,v) is evaluated per pixel in the fragment shader and
// depends on which corner and edge being evaluated. w(u,v) is the device-space W coordinate, so
// its reciprocal is provided in sk_FragCoord.w.
namespace skgpu::graphite {

using AAFlags = EdgeAAQuad::Flags;

static skvx::float4 load_x_radii(const SkRRect& rrect) {
    return skvx::float4{rrect.radii(SkRRect::kUpperLeft_Corner).fX,
                        rrect.radii(SkRRect::kUpperRight_Corner).fX,
                        rrect.radii(SkRRect::kLowerRight_Corner).fX,
                        rrect.radii(SkRRect::kLowerLeft_Corner).fX};
}
static skvx::float4 load_y_radii(const SkRRect& rrect) {
    return skvx::float4{rrect.radii(SkRRect::kUpperLeft_Corner).fY,
                        rrect.radii(SkRRect::kUpperRight_Corner).fY,
                        rrect.radii(SkRRect::kLowerRight_Corner).fY,
                        rrect.radii(SkRRect::kLowerLeft_Corner).fY};
}

static float local_aa_radius(const Transform& t, const SkV2& p) {
    // TODO: This should be the logic for Transform::scaleFactor()
    //              [m00 m01 * m03]                                 [f(u,v)]
    // Assuming M = [m10 m11 * m13], define the projected p'(u,v) = [g(u,v)] where
    //              [ *   *  *  * ]
    //              [m30 m31 * m33]
    //                                                        [x]     [u]
    // f(u,v) = x(u,v) / w(u,v), g(u,v) = y(u,v) / w(u,v) and [y] = M*[v]
    //                                                        [*] =   [0]
    //                                                        [w]     [1]
    //
    // x(u,v) = m00*u + m01*v + m03
    // y(u,v) = m10*u + m11*v + m13
    // w(u,v) = m30*u + m31*v + m33
    //
    // dx/du = m00, dx/dv = m01,
    // dy/du = m10, dy/dv = m11
    // dw/du = m30, dw/dv = m31
    //
    // df/du = (dx/du*w - x*dw/du)/w^2 = (m00*w - m30*x)/w^2 = (m00 - m30*f)/w
    // df/dv = (dx/dv*w - x*dw/dv)/w^2 = (m01*w - m31*x)/w^2 = (m01 - m31*f)/w
    // dg/du = (dy/du*w - y*dw/du)/w^2 = (m10*w - m30*y)/w^2 = (m10 - m30*g)/w
    // dg/dv = (dy/dv*w - y*dw/du)/w^2 = (m11*w - m31*y)/w^2 = (m11 - m31*g)/w
    //
    // Singular values of [df/du df/dv] define perspective correct minimum and maximum scale factors
    //                    [dg/du dg/dv]
    // for M evaluated at  (u,v)
    const SkM44& matrix = t.matrix();
    SkV4 devP = matrix.map(p.x, p.y, 0.f, 1.f);

    const float dxdu = matrix.rc(0,0);
    const float dxdv = matrix.rc(0,1);
    const float dydu = matrix.rc(1,0);
    const float dydv = matrix.rc(1,1);
    const float dwdu = matrix.rc(3,0);
    const float dwdv = matrix.rc(3,1);

    float invW2 = sk_ieee_float_divide(1.f, (devP.w * devP.w));
    // non-persp has invW2 = 1, devP.w = 1, dwdu = 0, dwdv = 0
    float dfdu = (devP.w*dxdu - devP.x*dwdu) * invW2; // non-persp -> dxdu -> m00
    float dfdv = (devP.w*dxdv - devP.x*dwdv) * invW2; // non-persp -> dxdv -> m01
    float dgdu = (devP.w*dydu - devP.y*dwdu) * invW2; // non-persp -> dydu -> m10
    float dgdv = (devP.w*dydv - devP.y*dwdv) * invW2; // non-persp -> dydv -> m11

    // no-persp, these are the singular values of [m00,m01][m10,m11], which is just the upper 2x2
    // and equivalent to SkMatrix::getMinmaxScales().
    float s1 = dfdu*dfdu + dfdv*dfdv + dgdu*dgdu + dgdv*dgdv;

    float e = dfdu*dfdu + dfdv*dfdv - dgdu*dgdu - dgdv*dgdv;
    float f = dfdu*dgdu + dfdv*dgdv;
    float s2 = SkScalarSqrt(e*e + 4*f*f);

    float singular1 = SkScalarSqrt(0.5f * (s1 + s2));
    float singular2 = SkScalarSqrt(0.5f * (s1 - s2));

    // singular1 and 2 represent the minimum and maximum scale factors at that transformed point.
    // Moving 1 from 'p' before transforming will move at least minimum and at most maximum from
    // the transformed point. Thus moving between [1/max, 1/min] pre-transformation means post
    // transformation moves between [1,max/min] so using 1/min as the local AA radius ensures that
    // the post-transformed point is at least 1px away from the original.
    float aaRadius = sk_ieee_float_divide(1.f, std::min(singular1, singular2));
    if (sk_float_isfinite(aaRadius)) {
        return aaRadius;
    } else {
        // Treat NaNs and infinities as +inf, which will always trigger the inset self-intersection
        // logic that snaps inner vertices to the center instead of insetting by the local AA radius
        return SK_FloatInfinity;
    }
}

static float local_aa_radius(const Transform& t, const Rect& bounds) {
    // Use the maximum radius of the 4 corners so that every local vertex uses the same offset
    // even if it's more conservative on some corners (when the min/max scale isn't constant due
    // to perspective).
    if (t.type() < Transform::Type::kProjection) {
        // Scale factors are constant, so the point doesn't really matter
        return local_aa_radius(t, SkV2{0.f, 0.f});
    } else {
        // TODO can we share calculation here?
        float tl = local_aa_radius(t, SkV2{bounds.left(), bounds.top()});
        float tr = local_aa_radius(t, SkV2{bounds.right(), bounds.top()});
        float br = local_aa_radius(t, SkV2{bounds.right(), bounds.bot()});
        float bl = local_aa_radius(t, SkV2{bounds.left(), bounds.bot()});
        return std::max(std::max(tl, tr), std::max(bl, br));
    }
}

static bool opposite_insets_intersect(const SkRRect& rrect, float strokeRadius, float aaRadius) {
    // One AA inset per side
    const float maxInset = strokeRadius + 2.f * aaRadius;
    return // Horizontal insets would intersect opposite corner's curve
           maxInset >= rrect.width() - rrect.radii(SkRRect::kLowerLeft_Corner).fX   ||
           maxInset >= rrect.width() - rrect.radii(SkRRect::kLowerRight_Corner).fX  ||
           maxInset >= rrect.width() - rrect.radii(SkRRect::kUpperLeft_Corner).fX   ||
           maxInset >= rrect.width() - rrect.radii(SkRRect::kUpperRight_Corner).fX  ||
           // Vertical insets would intersect opposite corner's curve
           maxInset >= rrect.height() - rrect.radii(SkRRect::kLowerLeft_Corner).fY  ||
           maxInset >= rrect.height() - rrect.radii(SkRRect::kLowerRight_Corner).fY ||
           maxInset >= rrect.height() - rrect.radii(SkRRect::kUpperLeft_Corner).fY  ||
           maxInset >= rrect.height() - rrect.radii(SkRRect::kUpperRight_Corner).fY;
}

static bool opposite_insets_intersect(const Rect& rect, float strokeRadius, float aaRadius) {
    return any(rect.size() <= 2.f * (strokeRadius + aaRadius));
}

static bool opposite_insets_intersect(const Geometry& geometry,
                                      float strokeRadius,
                                      float aaRadius) {
    if (geometry.isEdgeAAQuad()) {
        SkASSERT(strokeRadius == 0.f);
        const EdgeAAQuad& quad = geometry.edgeAAQuad();
        if (quad.edgeFlags() == AAFlags::kNone) {
            // If all edges are non-AA, there won't be any insetting. This allows completely non-AA
            // quads to use the fill triangles for simpler fragment shader work.
            return false;
        } else if (quad.isRect() && quad.edgeFlags() == AAFlags::kAll) {
            return opposite_insets_intersect(quad.bounds(), 0.f, aaRadius);
        } else {
            // Quads with mixed AA edges are tiles where non-AA edges must seam perfectly together.
            // If we were to inset along just the axis with AA at a corner, two adjacent quads could
            // arrive at slightly different inset coordinates and then we wouldn't have a perfect
            // mesh. Forcing insets to snap to the center means all non-AA edges are formed solely
            // by the original quad coordinates and should seam perfectly assuming perfect input.
            // The only downside to this is the fill triangles cannot be used since they would
            // partially extend into the coverage ramp from adjacent AA edges.
            return true;
        }
    } else {
        const Shape& shape = geometry.shape();
        if (shape.isRect()) {
            return opposite_insets_intersect(shape.rect(), strokeRadius, aaRadius);
        } else {
            SkASSERT(shape.isRRect());
            return opposite_insets_intersect(shape.rrect(), strokeRadius, aaRadius);
        }
    }
}

static bool is_clockwise(const EdgeAAQuad& quad) {
    if (quad.isRect()) {
        return true; // by construction, these are always locally clockwise
    }

    // This assumes that each corner has a consistent winding, which is the case for convex inputs,
    // which is an assumption of the per-edge AA API. Check the sign of cross product between the
    // first two edges.
    const skvx::float4& xs = quad.xs();
    const skvx::float4& ys = quad.ys();

    float winding = (xs[0] - xs[3])*(ys[1] - ys[0]) - (ys[0] - ys[3])*(xs[1] - xs[0]);
    if (winding == 0.f) {
        // The input possibly forms a triangle with duplicate vertices, so check the opposite corner
        winding = (xs[2] - xs[1])*(ys[3] - ys[2]) - (ys[2] - ys[1])*(xs[3] - xs[2]);
    }

    // At this point if winding is < 0, the quad's vertices are CCW. If it's still 0, the vertices
    // form a line, in which case the vertex shader constructs a correct CW winding. Otherwise,
    // the quad or triangle vertices produce a positive winding and are CW.
    return winding >= 0.f;
}

static skvx::float2 quad_center(const EdgeAAQuad& quad) {
    // The center of the bounding box is *not* a good center to use. Take the average of the
    // four points instead (which is slightly biased if they form a triangle, but still okay).
    return skvx::float2(dot(quad.xs(), skvx::float4(0.25f)),
                        dot(quad.ys(), skvx::float4(0.25f)));
}

// Represents the per-vertex attributes used in each instance.
struct Vertex {
    SkV2 fPosition;
    SkV2 fNormal;
    float fNormalScale;
    float fCenterWeight;
};

// Allowed values for the center weight instance value (selected at record time based on style
// and transform), and are defined such that when (insance-weight > vertex-weight) is true, the
// vertex should be snapped to the center instead of its regular calculation.
static constexpr float kSolidInterior = 1.f;
static constexpr float kStrokeInterior = 0.f;
static constexpr float kFilledStrokeInterior = -1.f;

// Special value for local AA radius to signal when the self-intersections of a stroke interior
// need extra calculations in the vertex shader.
static constexpr float kComplexAAInsets = -1.f;

static constexpr int kCornerVertexCount = 9; // sk_VertexID is divided by this in SkSL
static constexpr int kVertexCount = 4 * kCornerVertexCount;
static constexpr int kIndexCount = 69;

static void write_index_buffer(VertexWriter writer) {
    static constexpr uint16_t kTL = 0 * kCornerVertexCount;
    static constexpr uint16_t kTR = 1 * kCornerVertexCount;
    static constexpr uint16_t kBR = 2 * kCornerVertexCount;
    static constexpr uint16_t kBL = 3 * kCornerVertexCount;

    static const uint16_t kIndices[kIndexCount] = {
        // Exterior AA ramp outset
        kTL+0,kTL+4,kTL+1,kTL+5,kTL+2,kTL+3,kTL+5,
        kTR+0,kTR+4,kTR+1,kTR+5,kTR+2,kTR+3,kTR+5,
        kBR+0,kBR+4,kBR+1,kBR+5,kBR+2,kBR+3,kBR+5,
        kBL+0,kBL+4,kBL+1,kBL+5,kBL+2,kBL+3,kBL+5,
        kTL+0,kTL+4, // close and jump to next strip
        // Outer to inner edges
        kTL+4,kTL+6,kTL+5,kTL+7,
        kTR+4,kTR+6,kTR+5,kTR+7,
        kBR+4,kBR+6,kBR+5,kBR+7,
        kBL+4,kBL+6,kBL+5,kBL+7,
        kTL+4,kTL+6, // close and jump to next strip
        // Fill triangles
        kTL+6,kTL+8,kTL+7, kTL+7,kTR+8,
        kTR+6,kTR+8,kTR+7, kTR+7,kBR+8,
        kBR+6,kBR+8,kBR+7, kBR+7,kBL+8,
        kBL+6,kBL+8,kBL+7, kBL+7,kTL+8,
        kTL+6 // close
    };

    writer << kIndices;
}

static void write_vertex_buffer(VertexWriter writer) {
    // Allowed values for the normal scale attribute. +1 signals a device-space outset along the
    // normal away from the outer edge of the stroke. 0 signals no outset, but placed on the outer
    // edge of the stroke. -1 signals a local inset along the normal from the inner edge.
    static constexpr float kOutset = 1.0;
    static constexpr float kInset  = -1.0;

    static constexpr float kCenter = 1.f; // "true" as a float

    // Zero, but named this way to help call out non-zero parameters.
    static constexpr float _______ = 0.f;

    static constexpr float kHR2 = 0.5f * SK_FloatSqrt2; // "half root 2"

    // This template is repeated 4 times in the vertex buffer, for each of the four corners.
    // The vertex ID is used to lookup per-corner instance properties such as corner radii or
    // positions, but otherwise this vertex data produces a consistent clockwise mesh from
    // TL -> TR -> BR -> BL.
    static constexpr Vertex kCornerTemplate[kCornerVertexCount] = {
        // Device-space AA outsets from outer curve
        { {1.0f, 0.0f}, {1.0f, 0.0f}, kOutset, _______ },
        { {1.0f, 0.0f}, {kHR2, kHR2}, kOutset, _______ },
        { {0.0f, 1.0f}, {kHR2, kHR2}, kOutset, _______ },
        { {0.0f, 1.0f}, {0.0f, 1.0f}, kOutset, _______ },

        // Outer anchors (no local or device-space normal outset)
        { {1.0f, 0.0f}, {kHR2, kHR2}, _______, _______ },
        { {0.0f, 1.0f}, {kHR2, kHR2}, _______, _______ },

        // Inner curve (with additional AA inset in the common case)
        { {1.0f, 0.0f}, {1.0f, 0.0f}, kInset, _______ },
        { {0.0f, 1.0f}, {0.0f, 1.0f}, kInset, _______ },

        // Center filling vertices (equal to inner AA insets unless 'center' triggers a fill).
        // TODO: On backends that support "cull" distances (and with SkSL support), these vertices
        // and their corresponding triangles can be completely removed. The inset vertices can
        // set their cull distance value to cause all filling triangles to be discarded or not
        // depending on the instance's style.
        { {1.0f, 0.0f}, {1.0f, 0.0f}, kInset,  kCenter },
    };

    writer << kCornerTemplate  // TL
           << kCornerTemplate  // TR
           << kCornerTemplate  // BR
           << kCornerTemplate; // BL
}

AnalyticRRectRenderStep::AnalyticRRectRenderStep(StaticBufferManager* bufferManager)
        : RenderStep("AnalyticRRectRenderStep",
                     "",
                     Flags::kPerformsShading | Flags::kEmitsCoverage,
                     /*uniforms=*/{},
                     PrimitiveType::kTriangleStrip,
                     kDirectDepthGreaterPass,
                     /*vertexAttrs=*/{
                            {"position", VertexAttribType::kFloat2, SkSLType::kFloat2},
                            {"normal", VertexAttribType::kFloat2, SkSLType::kFloat2},
                            // TODO: These values are all +1/0/-1, or +1/0, so could be packed
                            // much more densely than as three floats.
                            {"normalScale", VertexAttribType::kFloat, SkSLType::kFloat},
                            {"centerWeight", VertexAttribType::kFloat, SkSLType::kFloat}
                     },
                     /*instanceAttrs=*/
                            {{"xRadiiOrFlags", VertexAttribType::kFloat4, SkSLType::kFloat4},
                             {"radiiOrQuadXs", VertexAttribType::kFloat4, SkSLType::kFloat4},
                             {"ltrbOrQuadYs", VertexAttribType::kFloat4, SkSLType::kFloat4},
                             // XY stores center of rrect in local coords. Z and W store values to
                             // control interior fill behavior. Z can be -1, 0, or 1:
                             //   -1: A stroked interior where AA insets overlap, but isn't solid.
                             //    0: A stroked interior with no complications.
                             //    1: A solid interior (fill or sufficiently large stroke width).
                             // W specifies the size of the AA inset if it's >= 0, or signals that
                             // the inner curves intersect in a complex manner (rare).
                             {"center", VertexAttribType::kFloat4, SkSLType::kFloat4},

                             // TODO: pack depth and ssboIndex into 32-bits
                             {"depth", VertexAttribType::kFloat, SkSLType::kFloat},
                             {"ssboIndex", VertexAttribType::kInt, SkSLType::kInt},

                             {"mat0", VertexAttribType::kFloat3, SkSLType::kFloat3},
                             {"mat1", VertexAttribType::kFloat3, SkSLType::kFloat3},
                             {"mat2", VertexAttribType::kFloat3, SkSLType::kFloat3}},
                     /*varyings=*/{
                             // TODO: If the inverse transform is part of the draw's SSBO, we can
                             // reconstruct the Jacobian in the fragment shader using the existing
                             // local coordinates varying
                             {"jacobian", SkSLType::kFloat4}, // float2x2
                             // Distance to LTRB edges of unstroked shape. Depending on
                             // 'perPixelControl' these will either be local or device-space values.
                             {"edgeDistances", SkSLType::kFloat4}, // distance to LTRB edges
                             // TODO: These are constant for all fragments for a given instance,
                             // could we store them in the draw's SSBO?
                             {"xRadii", SkSLType::kFloat4},
                             {"yRadii", SkSLType::kFloat4},
                             // Matches the StrokeStyle struct (X is radius, Y < 0 is round join,
                             // Y = 0 is bevel, Y > 0 is miter join).
                             // TODO: These could easily be considered part of the draw's uniforms.
                             {"strokeParams", SkSLType::kFloat2},
                             // 'perPixelControl' is a tightly packed description of how to
                             // evaluate the possible edges that influence coverage in a pixel.
                             // The decision points and encoded values are spread across X and Y
                             // so that they are consistent regardless of whether or not MSAA is
                             // used and does not require centroid sampling.
                             //
                             // The signs of values are used to determine the type of coverage to
                             // calculate in the fragment shader and depending on the state, extra
                             // varying state is encoded in the fields:
                             //  - A positive X value overrides all per-pixel coverage calculations
                             //    and sets the pixel to full coverage. Y is ignored in this case.
                             //  - A zero X value represents a solid interior shape.
                             //  - X much less than 0 represents bidirectional coverage for a
                             //    stroke, using a sufficiently negative value to avoid
                             //    extrapolation from fill triangles. For actual shapes with
                             //    bidirectional coverage, the fill triangles are zero area.
                             //
                             //  - Y much greater than 0 takes precedence over the latter two X
                             //    rules and signals that 'edgeDistances' holds device-space values
                             //    and does not require additional per-pixel calculations. The
                             //    coverage scale is encoded as (1+scale*w) and the bias is
                             //    reconstructed from that. X is always 0 for non-fill triangles
                             //    since device-space edge distance is only used for solid interiors
                             //  - Otherwise, any negative Y value represents an additional
                             //    reduction in coverage due to a device-space outset. It is clamped
                             //    below 0 to avoid adding coverage from extrapolation.
                             {"perPixelControl", SkSLType::kFloat2},
                     }) {
    // Initialize the static buffers we'll use when recording draw calls.
    // NOTE: Each instance of this RenderStep gets its own copy of the data. Since there should only
    // ever be one AnalyticRRectRenderStep at a time, this shouldn't be an issue.
    write_vertex_buffer(bufferManager->getVertexWriter(sizeof(Vertex) * kVertexCount,
                                                       &fVertexBuffer));
    write_index_buffer(bufferManager->getIndexWriter(sizeof(uint16_t) * kIndexCount,
                                                     &fIndexBuffer));
}

AnalyticRRectRenderStep::~AnalyticRRectRenderStep() {}

std::string AnalyticRRectRenderStep::vertexSkSL() const {
    // TODO: Move this into a module
    return R"(
        const int kCornerVertexCount = 9; // KEEP IN SYNC WITH C++'s kCornerVertexCount
        const float kMiterScale = 1.0;
        const float kBevelScale = 0.0;
        const float kRoundScale = 0.41421356237; // sqrt(2)-1

        const float kEpsilon = 0.00024; // SK_ScalarNearlyZero

        // Default to miter'ed vertex positioning. Corners with sufficiently large corner radii, or
        // bevel'ed strokes will adjust vertex placement on a per corner basis. This will not affect
        // the final coverage calculations in the fragment shader.
        float joinScale = kMiterScale;

        // Unpack instance-level state that determines the vertex placement and style of shape.
        bool bidirectionalCoverage = center.z <= 0.0;
        bool deviceSpaceDistances = false;
        float4 xs, ys; // ordered TL, TR, BR, BL
        if (xRadiiOrFlags.x < -1.0) {
            // Stroked rect or round rect
            xs = ltrbOrQuadYs.LRRL;
            ys = ltrbOrQuadYs.TTBB;

            if (xRadiiOrFlags.y < 0.0) {
                // A hairline so the X radii are encoded as negative values in this field, and Y
                // radii are stored directly in the subsequent float4.
                xRadii = -xRadiiOrFlags - 2.0;
                yRadii = radiiOrQuadXs;

                // All hairlines use miter joins (join style > 0)
                strokeParams = float2(0.0, 1.0);
            } else {
                xRadii = radiiOrQuadXs;
                yRadii = xRadii; // regular strokes are circular
                strokeParams = xRadiiOrFlags.zw;

                if (strokeParams.y < 0.0) {
                    joinScale = kRoundScale; // the stroke radius rounds rectangular corners
                }  else if (strokeParams.y == 0.0) {
                    joinScale = kBevelScale;
                } // else stay mitered
            }
        } else if (any(greaterThan(xRadiiOrFlags, float4(0.0)))) {
            // Filled round rect
            xs = ltrbOrQuadYs.LRRL;
            ys = ltrbOrQuadYs.TTBB;

            xRadii = xRadiiOrFlags;
            yRadii = radiiOrQuadXs;

            strokeParams = float2(0.0, -1.0); // A negative join style is "round"
        } else {
            // Per-edge quadrilateral, so we have to calculate the corner's basis from the
            // quad's edges.
            xs = radiiOrQuadXs;
            ys = ltrbOrQuadYs;

            xRadii = float4(0.0);
            yRadii = float4(0.0);

            strokeParams = float2(0.0, 1.0); // Will be ignored, but set to a "miter"
            deviceSpaceDistances = true;
        }

        // Adjust state on a per-corner basis
        int cornerID = sk_VertexID / kCornerVertexCount;
        float strokeRadius = strokeParams.x; // alias
        float2 cornerRadii = float2(xRadii[cornerID], yRadii[cornerID]);
        if (cornerID % 2 != 0) {
            // Corner radii are uploaded in the local coordinate frame, but vertex placement happens
            // in a consistent winding before transforming to final local coords, so swap the
            // radii for odd corners.
            cornerRadii = cornerRadii.yx;
        }

        float2 cornerAspectRatio = float2(1.0);
        if (cornerRadii.x > kEpsilon && cornerRadii.y > kEpsilon) {
            // Position vertices for an elliptical corner; overriding any previous join style since
            // that only applies when radii are 0.
            joinScale = kRoundScale;
            cornerAspectRatio = cornerRadii.yx;
        } else if (cornerRadii.x != 0 && cornerRadii.y != 0) {
            // A very small rounded corner, which technically ignores style (i.e. should not be
            // beveled or mitered), but place the vertices as a miter to fully cover it and let
            // the fragment shader evaluate the curve per pixel.
            joinScale = kMiterScale;
            cornerAspectRatio = cornerRadii.yx;
            cornerRadii = float2(0.0);
        } else if (strokeRadius > 0.0 && strokeRadius <= kEpsilon) {
            // A stroked rectangular corner that could have a very small bevel or round join,
            // so place vertices as a miter.
            joinScale = kMiterScale;
        }

        // Calculate the local edge vectors, ordered L, T, R, B starting from the bottom left point.
        // For quadrilaterals these are not necessarily axis-aligned, but in all cases they orient
        // the +X/+Y normalized vertex template for each corner.
        // TODO: Correct edge vectors for points, lines, and triangles.
        float4 dx = xs - xs.wxyz;
        float4 dy = ys - ys.wxyz;
        float4 invEdgeLen = inversesqrt(dx*dx + dy*dy);
        dx *= invEdgeLen;
        dy *= invEdgeLen;

        // Calculate local coordinate for the vertex (relative to xAxis and yAxis at first).
        float2 xAxis = -float2(dx.yzwx[cornerID], dy.yzwx[cornerID]);
        float2 yAxis =  float2(dx.xyzw[cornerID], dy.xyzw[cornerID]);
        float2 localPos;
        bool snapToCenter = false;
        if (normalScale < 0.0) {
            // Vertex is inset from the base shape, so we scale by (cornerRadii - strokeRadius)
            // and have to check for the possibility of an inner miter. It is always inset by an
            // additional conservative AA amount.
            if (center.w < 0.0 || centerWeight * center.z != 0.0) {
                snapToCenter = true;
            } else {
                float localAARadius = center.w;
                float2 insetRadii =
                        cornerRadii + (bidirectionalCoverage ? -strokeRadius : strokeRadius);
                if (joinScale == kMiterScale ||
                    insetRadii.x <= localAARadius || insetRadii.y <= localAARadius) {
                    // Miter the inset position
                    localPos = (insetRadii - localAARadius);
                } else {
                    localPos = insetRadii*position - localAARadius*normal;
                }
            }
        } else {
            // Vertex is outset from the base shape (and possibly with an additional AA outset later
            // in device space).
            localPos = (cornerRadii + strokeRadius) * (position + joinScale*position.yx);
        }

        if (snapToCenter) {
            // Center is already relative to true local coords, not the corner basis.
            localPos = center.xy;
        } else {
            // Transform from corner basis to true local coords.
            localPos -= cornerRadii;
            localPos = float2(xs[cornerID], ys[cornerID]) + xAxis*localPos.x + yAxis*localPos.y;
        }

        // Calculate edge distances and device space coordinate for the vertex
        // TODO: Apply edge AA flags to these values to turn off AA when necessary.
        edgeDistances = dy*(xs - localPos.x) - dx*(ys - localPos.y);

        float3x3 localToDevice = float3x3(mat0, mat1, mat2);
        // NOTE: This 3x3 inverse is different than just taking the 1st two columns of the 4x4
        // inverse of the original SkM44 local-to-device matrix. We could calculate the 3x3 inverse
        // and upload it, but it does not seem to be a bottleneck and saves on bandwidth to
        // calculate it here instead.
        float3x3 deviceToLocal = inverse(localToDevice);
        float3 devPos = localToDevice * localPos.xy1;
        jacobian = float4(deviceToLocal[0].xy - deviceToLocal[0].z*localPos,
                          deviceToLocal[1].xy - deviceToLocal[1].z*localPos);

        if (deviceSpaceDistances) {
            // Apply the Jacobian in the vertex shader so any quadrilateral normals do not have to
            // be passed to the fragment shader. However, it's important to use the Jacobian at a
            // vertex on the edge, not the current vertex's Jacobian.
            float4 gx = -dy*(deviceToLocal[0].x - deviceToLocal[0].z*xs) +
                         dx*(deviceToLocal[0].y - deviceToLocal[0].z*ys);
            float4 gy = -dy*(deviceToLocal[1].x - deviceToLocal[1].z*xs) +
                         dx*(deviceToLocal[1].y - deviceToLocal[1].z*ys);
            // NOTE: The gradient is missing a W term so edgeDistances must still be multiplied by
            // 1/w in the fragment shader. The same goes for the encoded coverage scale.
            edgeDistances *= inversesqrt(gx*gx + gy*gy);

            float2 dim = edgeDistances.xy + edgeDistances.zw;
            // TODO: Mixed AA flags should always use the (1,0.5) scale and bias since the set of
            // tiled quads forms a larger shape that would not get subpixel treatment.
            perPixelControl.y = 1.0 + min(min(dim.x, dim.y), abs(devPos.z));
        }

        // Only outset for a vertex that is in front of the w=0 plane to avoid dealing with outset
        // triangles rasterizing differently from the main triangles as w crosses 0.
        if (normalScale > 0.0 && devPos.z > 0.0) {
            // Note that when there's no perspective, the jacobian is equivalent to the normal
            // matrix (inverse transpose), but produces correct results when there's perspective
            // because it accounts for the position's influence on a line's projected direction.
            float2x2 J = float2x2(jacobian.xy, jacobian.zw);
            float2 nx = cornerAspectRatio.x * normal.x * perp(-yAxis) * J;
            float2 ny = cornerAspectRatio.y * normal.y * perp( xAxis) * J;

            bool isMidVertex = normal.x != 0.0 && normal.y != 0.0;
            if (joinScale == kMiterScale && isMidVertex) {
                // Produce a bisecting vector in device space (ignoring 'normal' since that was
                // previously corrected to match the mitered edge normals).
                nx = normalize(nx);
                ny = normalize(ny);
                if (dot(nx, ny) < -0.8) {
                    // Normals are in nearly opposite directions, so adjust to avoid float error.
                    float s = sign(cross_length_2d(nx, ny));
                    nx =  s*perp(nx);
                    ny = -s*perp(ny);
                }
            }
            // Adding the normal components together directly results in what we'd have
            // calculated if we'd just transformed 'normal' in one go, assuming they weren't
            // normalized in the if-block above. If they were normalized, the sum equals the
            // bisector between the original nx and ny.
            //
            // We multiply by W so that after perspective division the new point is offset by the
            // now-unit normal.
            devPos.xy += devPos.z * normalize(nx + ny);

            // By construction these points are 1px away from the outer edge in device space.
            if (deviceSpaceDistances) {
                // Apply directly to edgeDistances to save work per pixel later on.
                edgeDistances -= devPos.z;
            } else {
                // Otherwise store separately so edgeDistances can be used to reconstruct corner pos
                perPixelControl.y = -devPos.z;
            }
        } else if (!deviceSpaceDistances) {
            // Triangles are within the original shape so there's no additional outsetting to
            // take into account for coverage calculations.
            perPixelControl.y = 0.0;
        }

        if (centerWeight != 0.0) {
            // A positive value signals that a pixel is trivially full coverage.
            perPixelControl.x = 1.0;
        } else {
            // A negative value signals bidirectional coverage, and a zero value signals a solid
            // interior with per-pixel coverage.
            perPixelControl.x = bidirectionalCoverage ? -1.0 : 0.0;
        }

        // Write out final results
        stepLocalCoords = localPos;
        float4 devPosition = float4(devPos.xy, devPos.z*depth, devPos.z);
    )";
}

const char* AnalyticRRectRenderStep::fragmentCoverageSkSL() const {
    // TODO: Further modularize this
    return R"(
        if (perPixelControl.x > 0.0) {
            // A trivially solid interior pixel, either from a filled rect or round rect, or a
            // stroke with sufficiently large width that the interior completely overlaps itself.
            outputCoverage = half4(1.0);
        } else if (perPixelControl.y > 1.0) {
            // This represents a filled rectangle or quadrilateral, where the distances have already
            // been converted to device space. Mitered strokes cannot use this optimization because
            // their scale and bias is not uniform over the shape; Rounded shapes cannot use this
            // because they rely on the edge distances being in local space to reconstruct the
            // per-corner positions for the elliptical implicit functions.
            float2 outerDist = min(edgeDistances.xy, edgeDistances.zw);
            float c = min(outerDist.x, outerDist.y) * sk_FragCoord.w;
            float scale = (perPixelControl.y - 1.0) * sk_FragCoord.w;
            float bias = coverage_bias(scale);
            outputCoverage = half4(clamp(scale * (c + bias), 0.0, 1.0));
        } else {
            // Compute per-pixel coverage, mixing four outer edge distances, possibly four inner
            // edge distances, and per-corner elliptical distances into a final coverage value.
            // The Jacobian needs to be multiplied by W, but sk_FragCoord.w stores 1/w.
            float2x2 J = float2x2(jacobian.xy, jacobian.zw) / sk_FragCoord.w;

            float2 invGradLen = float2(inverse_grad_len(float2(1.0, 0.0), J),
                                       inverse_grad_len(float2(0.0, 1.0), J));
            float2 outerDist = invGradLen * (strokeParams.x + min(edgeDistances.xy,
                                                                  edgeDistances.zw));

            // d.x tracks minimum outer distance (pre scale-and-biasing to a coverage value).
            // d.y tracks negative maximum inner distance (so min() over c accumulates min and outer
            // and max inner simultaneously).)
            float2 d = float2(min(outerDist.x, outerDist.y), -1.0);
            float scale, bias;

            // Check for bidirectional coverage, which is is marked as a -1 from the vertex shader.
            // We don't just check for < 0 since extrapolated fill triangle samples can have small
            // negative values.
            if (perPixelControl.x > -0.95) {
                // A solid interior, so update scale and bias based on full width and height
                float2 dim = invGradLen * (edgeDistances.xy + edgeDistances.zw + 2*strokeParams.xx);
                scale = min(min(dim.x, dim.y), 1.0);
                bias = coverage_bias(scale);
                // Since we leave d.y = -1.0, no inner curve coverage will adjust it closer to 0,
                // so 'finalCoverage' is based solely on outer edges and curves.
            } else {
                // Bidirectional coverage, so we modify c.y to hold the negative of the maximum
                // interior coverage, and update scale and bias based on stroke width.
                float2 strokeWidth = 2.0 * strokeParams.x * invGradLen;
                float2 innerDist = strokeWidth - outerDist;

                d.y = -max(innerDist.x, innerDist.y);
                if (strokeParams.x > 0.0) {
                    float strokeDim = min(strokeWidth.x, strokeWidth.y);
                    if (innerDist.y >= -0.5 && strokeWidth.y > strokeDim) {
                        strokeDim = strokeWidth.y;
                    }
                    if (innerDist.x >= -0.5 && strokeWidth.x > strokeDim) {
                        strokeDim = strokeWidth.x;
                    }
                    scale = min(strokeDim, 1.0);
                    bias = coverage_bias(scale);
                } else {
                    // A hairline, so scale and bias should both be 1
                     scale = bias = 1.0;
                }
            }

            // Check all corners, although most pixels should only be influenced by 1.
            corner_distances(d, J, strokeParams, edgeDistances, xRadii, yRadii);

            float outsetDist = min(perPixelControl.y, 0.0) * sk_FragCoord.w;
            float finalCoverage = scale * (min(d.x + outsetDist, -d.y) + bias);

            outputCoverage = half4(clamp(finalCoverage, 0.0, 1.0));
        }
    )";
}

void AnalyticRRectRenderStep::writeVertices(DrawWriter* writer,
                                           const DrawParams& params,
                                           int ssboIndex) const {
    SkASSERT(params.geometry().isShape() || params.geometry().isEdgeAAQuad());

    DrawWriter::Instances instance{*writer, fVertexBuffer, fIndexBuffer, kIndexCount};
    auto vw = instance.append(1);

    // The bounds of a rect is the rect, and the bounds of a rrect is tight (== SkRRect::getRect()).
    Rect bounds = params.geometry().bounds();

    // aaRadius will be set to a negative value to signal a complex self-intersection that has to
    // be calculated in the vertex shader.
    float aaRadius = local_aa_radius(params.transform(), bounds);
    float strokeInset = 0.f;
    float centerWeight = kSolidInterior;

    if (params.isStroke()) {
        const Shape& shape = params.geometry().shape(); // EdgeAAQuads are not stroked

        SkASSERT(params.strokeStyle().halfWidth() >= 0.f);
        SkASSERT(shape.isRect() || params.strokeStyle().halfWidth() == 0.f ||
                 (shape.isRRect() && SkRRectPriv::AllCornersCircular(shape.rrect())));

        const float strokeRadius = params.strokeStyle().halfWidth();
        skvx::float2 innerGap = bounds.size() - 2.f * params.strokeStyle().halfWidth();
        if (any(innerGap <= 0.f)) {
            // AA inset intersections are measured from the *outset*
            strokeInset = -strokeRadius;
        } else {
            // This will be upgraded to kFilledStrokeInterior if insets intersect
            centerWeight = kStrokeInterior;
            strokeInset = strokeRadius;
        }

        skvx::float4 xRadii = shape.isRRect() ? load_x_radii(shape.rrect()) : skvx::float4(0.f);
        if (params.strokeStyle().halfWidth() > 0.f) {
            float joinStyle = params.strokeStyle().joinLimit();
            if (params.strokeStyle().isMiterJoin()) {
                // All corners are 90-degrees so become beveled if the miter limit is < sqrt(2).
                if (params.strokeStyle().miterLimit() < SK_ScalarSqrt2) {
                    joinStyle = 0.f; // == bevel
                } else {
                    // Discard actual miter limit because a 90-degree corner never exceeds it.
                    joinStyle = 1.f;
                }
            }
            // Write a negative value outside [-1, 0] to signal a stroked shape, then the style
            // params, followed by corner radii and bounds.
            vw << -2.f << 0.f << strokeRadius << joinStyle << xRadii << bounds.ltrb();
        } else {
            // Write -2 - cornerRadii to encode the X radii in such a way to trigger stroking but
            // guarantee the 2nd field is non-zero to signal hairline. Then we upload Y radii as
            // well to allow for elliptical hairlines.
            skvx::float4 yRadii = shape.isRRect() ? load_y_radii(shape.rrect()) : skvx::float4(0.f);
            vw << (-2.f - xRadii) << yRadii << bounds.ltrb();
        }
    } else {
        if (params.geometry().isEdgeAAQuad()) {
            // NOTE: If quad.isRect() && quad.edgeFlags() == kAll, the written data is identical to
            // Shape.isRect() case below.
            const EdgeAAQuad& quad = params.geometry().edgeAAQuad();

            // If all edges are non-AA, set localAARadius to 0 so that the fill triangles cover the
            // entire shape. Otherwise leave it as-is for the full AA rect case; in the event it's
            // mixed-AA or a quad, it'll be converted to complex insets down below.
            if (quad.edgeFlags() == EdgeAAQuad::Flags::kNone) {
                aaRadius = 0.f;
            }

            // -1 for AA on, 0 for AA off
            auto edgeSigns = skvx::float4{quad.edgeFlags() & AAFlags::kLeft   ? -1.f : 0.f,
                                          quad.edgeFlags() & AAFlags::kTop    ? -1.f : 0.f,
                                          quad.edgeFlags() & AAFlags::kRight  ? -1.f : 0.f,
                                          quad.edgeFlags() & AAFlags::kBottom ? -1.f : 0.f};

            // The vertex shader expects points to be in clockwise order. EdgeAAQuad is the only
            // shape that *might* have counter-clockwise input.
            if (is_clockwise(quad)) {
                vw << edgeSigns << quad.xs() << quad.ys();
            } else {
                vw << skvx::shuffle<2,1,0,3>(edgeSigns)  // swap left and right AA bits
                   << skvx::shuffle<1,0,3,2>(quad.xs())  // swap TL with TR, and BL with BR
                   << skvx::shuffle<1,0,3,2>(quad.ys()); //   ""
            }
        } else {
            const Shape& shape = params.geometry().shape();
            if (shape.isRect() || (shape.isRRect() && shape.rrect().isRect())) {
                // Rectangles (or rectangles embedded in an SkRRect) are converted to the
                // quadrilateral case, but with all edges anti-aliased (== -1).
                skvx::float4 ltrb = bounds.ltrb();
                vw << /*edge flags*/ skvx::float4(-1.f)
                   << /*xs*/ skvx::shuffle<0,2,2,0>(ltrb)
                   << /*ys*/ skvx::shuffle<1,1,3,3>(ltrb);
            } else {
                // A filled rounded rectangle, so make sure at least one corner radii > 0 or the
                // shader won't detect it as a rounded rect.
                SkASSERT(any(load_x_radii(shape.rrect()) > 0.f));

                vw << load_x_radii(shape.rrect()) << load_y_radii(shape.rrect()) << bounds.ltrb();
            }
        }
    }

    if (opposite_insets_intersect(params.geometry(), strokeInset, aaRadius)) {
        aaRadius = kComplexAAInsets;
        if (centerWeight == kStrokeInterior) {
            centerWeight = kFilledStrokeInterior;
        }
    }

    // All instance types share the remaining instance attribute definitions
    const SkM44& m = params.transform().matrix();
    auto center = params.geometry().isEdgeAAQuad() ? quad_center(params.geometry().edgeAAQuad())
                                                   : bounds.center();
    vw << center << centerWeight << aaRadius
       << params.order().depthAsFloat()
       << ssboIndex
       << m.rc(0,0) << m.rc(1,0) << m.rc(3,0)  // mat0
       << m.rc(0,1) << m.rc(1,1) << m.rc(3,1)  // mat1
       << m.rc(0,3) << m.rc(1,3) << m.rc(3,3); // mat2
}

void AnalyticRRectRenderStep::writeUniformsAndTextures(const DrawParams&,
                                                       PipelineDataGatherer*) const {
    // All data is uploaded as instance attributes, so no uniforms are needed.
}

}  // namespace skgpu::graphite
