/*
 * Copyright 2024 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/CircularArcRenderStep.h"

#include "include/core/SkArc.h"
#include "include/core/SkM44.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/private/SkAssert.h"
#include "include/private/SkDebug.h"
#include "include/private/SkEnumBitMask.h"
#include "src/core/SkSLTypeShared.h"
#include "src/gpu/BufferWriter.h"
#include "src/gpu/graphite/Attribute.h"
#include "src/gpu/graphite/BufferManager.h"
#include "src/gpu/graphite/DrawOrder.h"
#include "src/gpu/graphite/DrawParams.h"
#include "src/gpu/graphite/DrawTypes.h"
#include "src/gpu/graphite/DrawWriter.h"
#include "src/gpu/graphite/PipelineData.h"
#include "src/gpu/graphite/geom/Geometry.h"
#include "src/gpu/graphite/geom/Shape.h"
#include "src/gpu/graphite/geom/Transform.h"
#include "src/gpu/graphite/render/CommonDepthStencilSettings.h"

#include <utility>

// This RenderStep is used to render filled circular arcs and stroked circular arcs that
// don't include the center. Currently it only supports butt caps but will be extended
// to include round caps.
//
// Each arc is represented by a single instance. The instance attributes are enough to
// describe the given arc types without relying on uniforms to define its operation.
// The attributes encode shape as follows:

// float4 centerScales - used to transform the vertex data into local space.
//    The vertex data represents interleaved octagons that are respectively circumscribed
//    and inscribed on a unit circle, and have to be transformed into local space.
//    So the .xy values here are the center of the arc in local space, and .zw its outer and inner
//    radii, respectively. If the vertex is an outer vertex its local position will be computed as
//         centerScales.xy + position.xy * centerScales.z
//    Otherwise it will be computed as
//         centerScales.xy + position.xy * centerScales.w
//    We can tell whether a vertex is an outer or inner vertex by looking at the sign
//    of its z component. This z value is also used to compute half-pixel anti-aliasing offsets
//    once the vertex data is transformed into device space.
// float3 radiiAndFlags - in the fragment shader we will pass an offset in unit circle space to
//    determine the circle edge and for use for clipping. The .x value here is outerRadius+0.5 and
//    will be compared against the unit circle radius (i.e., 1.0) to compute the outer edge. The .y
//    value is innerRadius-0.5/outerRadius+0.5 and will be used as the comparison point for the
//    inner edge. The .z value is a flag which indicates whether fragClipPlane1 is for intersection
//    (+) or for union (-), and whether to set up rounded caps (-2/+2).
// float3 geoClipPlane - For very thin acute arcs, because of the 1/2 pixel boundary we can get
//    non-clipped artifacts beyond the center of the circle. To solve this, we clip the geometry
//    so any rendering doesn't cross that point.

// In addition, these values will be passed to the fragment shader:
//
// float3 fragClipPlane0 - the arc will always be clipped against this half plane, and passed as
//    the varying clipPlane.
// float3 fragClipPlane1 - for convex/acute arcs, we pass this via the varying isectPlane to clip
//    against this and multiply its value by the ClipPlane clip result. For concave/obtuse arcs,
//    we pass this via the varying unionPlane which will clip against this and add its value to the
//    ClipPlane clip result. This is controlled by the flag value in radiiAndFlags: if the
//    flag is > 0, it's passed as isectClip, if it's < 0 it's passed as unionClip. We set default
//    values for the alternative clip plane that end up being a null clip.
// float  roundCapRadius - this is computed in the vertex shader. If we're using round caps (i.e.,
//    if abs(flags) > 1), this will be half the distance between the outer and inner radii.
//    Otherwise it will be 0 which will end up zeroing out any round cap calculation.
// float4 inRoundCapPos - locations of the centers of the round caps in normalized space. This
//    will be all zeroes if not needed.

namespace skgpu::graphite {

// Represents the per-vertex attributes used in each instance.
struct Vertex {
    // Unit circle local space position (.xy) and AA offset (.z)
    SkV3 fPosition;
};

static constexpr int kVertexCount = 18;

static void write_vertex_buffer(VertexWriter writer) {
    // Normalized geometry for octagons that circumscribe/inscribe a unit circle.
    // Outer ring offset
    static constexpr float kOctOffset = 0.41421356237f;  // sqrt(2) - 1
    // Inner ring points
    static constexpr SkScalar kCosPi8 = 0.923579533f;
    static constexpr SkScalar kSinPi8 = 0.382683432f;

    // Directional offset for anti-aliasing.
    // Also used as marker for whether this is an outer or inner vertex.
    static constexpr float kOuterAAOffset = 0.5f;
    static constexpr float kInnerAAOffset = -0.5f;

    static constexpr SkV3 kOctagonVertices[kVertexCount] = {
        {-kOctOffset, -1,          kOuterAAOffset},
        {-kSinPi8,    -kCosPi8,    kInnerAAOffset},
        { kOctOffset, -1,          kOuterAAOffset},
        {kSinPi8,     -kCosPi8,    kInnerAAOffset},
        { 1,          -kOctOffset, kOuterAAOffset},
        {kCosPi8,     -kSinPi8,    kInnerAAOffset},
        { 1,           kOctOffset, kOuterAAOffset},
        {kCosPi8,      kSinPi8,    kInnerAAOffset},
        { kOctOffset,  1,          kOuterAAOffset},
        {kSinPi8,      kCosPi8,    kInnerAAOffset},
        {-kOctOffset,  1,          kOuterAAOffset},
        {-kSinPi8,     kCosPi8,    kInnerAAOffset},
        {-1,           kOctOffset, kOuterAAOffset},
        {-kCosPi8,     kSinPi8,    kInnerAAOffset},
        {-1,          -kOctOffset, kOuterAAOffset},
        {-kCosPi8,    -kSinPi8,    kInnerAAOffset},
        {-kOctOffset, -1,          kOuterAAOffset},
        {-kSinPi8,    -kCosPi8,    kInnerAAOffset},
    };

    if (writer) {
        writer << kOctagonVertices;
    } // otherwise static buffer creation failed, so do nothing; Context initialization will fail.
}

CircularArcRenderStep::CircularArcRenderStep(Layout layout, StaticBufferManager* bufferManager)
        : RenderStep(layout,
                     RenderStepID::kCircularArc,
                     Flags::kPerformsShading | Flags::kEmitsCoverage | Flags::kOutsetBoundsForAA |
                     Flags::kAppendInstances,
                     /*uniforms=*/{},
                     PrimitiveType::kTriangleStrip,
                     kDirectDepthLessPass,
                     /*staticAttrs=*/{{
                             {"position", VertexAttribType::kFloat3, SkSLType::kFloat3},
                     }},
                     /*appendAttrs=*/{{
                             // Center plus radii, used to transform to local position
                             {"centerScales", VertexAttribType::kFloat4, SkSLType::kFloat4},
                             // Outer (device space) and inner (normalized) radii
                             // + flags for determining clipping and roundcaps
                             {"radiiAndFlags", VertexAttribType::kFloat3, SkSLType::kFloat3},
                             // Clips the geometry for acute arcs
                             {"geoClipPlane", VertexAttribType::kFloat3, SkSLType::kFloat3},
                             // Clip planes sent to the fragment shader for arc extents
                             {"fragClipPlane0", VertexAttribType::kFloat3, SkSLType::kFloat3},
                             {"fragClipPlane1", VertexAttribType::kFloat3, SkSLType::kFloat3},
                             // Roundcap positions, if needed
                             {"inRoundCapPos", VertexAttribType::kFloat4, SkSLType::kFloat4},
                             {"inRoundCapRadius", VertexAttribType::kFloat, SkSLType::kFloat},
                             {"depth", VertexAttribType::kFloat, SkSLType::kFloat},
                             {"ssboIndex", VertexAttribType::kUInt, SkSLType::kUInt},

                             {"mat0", VertexAttribType::kFloat3, SkSLType::kFloat3},
                             {"mat1", VertexAttribType::kFloat3, SkSLType::kFloat3},
                             {"mat2", VertexAttribType::kFloat3, SkSLType::kFloat3},
                     }},
                     /*varyings=*/{{
                             // Normalized offset vector plus radii
                             {"circleEdge", SkSLType::kFloat4},
                             // Half-planes used to clip to arc shape.
                             {"clipPlane", SkSLType::kFloat3},
                             {"isectPlane", SkSLType::kFloat3},
                             {"unionPlane", SkSLType::kFloat3},
                             // Roundcap data
                             {"roundCapRadius", SkSLType::kFloat},
                             {"roundCapPos", SkSLType::kFloat4},
                     }}) {
    // Initialize the static buffer 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 CircularArcRenderStep at a time, this shouldn't be an issue.
    write_vertex_buffer(bufferManager->getVertexWriter(kVertexCount, sizeof(Vertex),
                                                       &fVertexBuffer));
}

CircularArcRenderStep::~CircularArcRenderStep() {}

std::string CircularArcRenderStep::vertexSkSL() const {
    // Returns the body of a vertex function, which must define a float4 devPosition variable and
    // must write to an already-defined float2 stepLocalCoords variable.
    return "float4 devPosition = circular_arc_vertex_fn("
                   // Static Data Attributes
                   "position, "
                   // Append Data Attributes
                   "centerScales, radiiAndFlags, geoClipPlane, fragClipPlane0, fragClipPlane1, "
                   "inRoundCapPos, inRoundCapRadius, depth, float3x3(mat0, mat1, mat2), "
                   // Varyings
                   "circleEdge, clipPlane, isectPlane, unionPlane, "
                   "roundCapRadius, roundCapPos, "
                   // Render Step
                   "stepLocalCoords);\n";
}

const char* CircularArcRenderStep::fragmentCoverageSkSL() const {
    // The returned SkSL must write its coverage into a 'half4 outputCoverage' variable (defined in
    // the calling code) with the actual coverage splatted out into all four channels.
    return "outputCoverage = circular_arc_coverage_fn(circleEdge, "
                                                     "clipPlane, "
                                                     "isectPlane, "
                                                     "unionPlane, "
                                                     "roundCapRadius, "
                                                     "roundCapPos);";
}

void CircularArcRenderStep::writeVertices(DrawWriter* writer,
                                          const DrawParams& params,
                                          uint32_t ssboIndex) const {
    SkASSERT(params.geometry().isShape() && params.geometry().shape().isArc());

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

    const Shape& shape = params.geometry().shape();
    const SkArc& arc = shape.arc();

    SkPoint localCenter = arc.oval().center();
    float localOuterRadius = arc.oval().width() / 2;
    float localInnerRadius = 0.0f;

    // We know that we have a similarity matrix so this will transform radius to device space
    const Transform& transform = params.transform();
    float radius = localOuterRadius * transform.maxScaleFactor();
    bool isStroke = params.isStroke();

    float innerRadius = -SK_ScalarHalf;
    float outerRadius = radius;
    float halfWidth = 0;
    if (isStroke) {
        float localHalfWidth = params.strokeStyle().halfWidth();

        halfWidth = localHalfWidth * transform.maxScaleFactor();
        if (SkScalarNearlyZero(halfWidth)) {
            halfWidth = SK_ScalarHalf;
            // Need to map this back to local space
            localHalfWidth = halfWidth / transform.maxScaleFactor();
        }

        outerRadius += halfWidth;
        innerRadius = radius - halfWidth;
        localInnerRadius = localOuterRadius - localHalfWidth;
        localOuterRadius += localHalfWidth;
    }

    // The radii are outset for two reasons. First, it allows the shader to simply perform
    // simpler computation because the computed alpha is zero, rather than 50%, at the radius.
    // Second, the outer radius is used to compute the verts of the bounding box that is
    // rendered and the outset ensures the box will cover all partially covered by the circle.
    outerRadius += SK_ScalarHalf;
    innerRadius -= SK_ScalarHalf;

    // The shader operates in a space where the circle is translated to be centered at the
    // origin. Here we compute points on the unit circle at the starting and ending angles.
    SkV2 localPoints[3];
    float startAngleRadians = SkDegreesToRadians(arc.startAngle());
    float sweepAngleRadians = SkDegreesToRadians(arc.sweepAngle());
    localPoints[0].y = SkScalarSin(startAngleRadians);
    localPoints[0].x = SkScalarCos(startAngleRadians);
    SkScalar endAngle = startAngleRadians + sweepAngleRadians;
    localPoints[1].y = SkScalarSin(endAngle);
    localPoints[1].x = SkScalarCos(endAngle);
    localPoints[2] = {0, 0};

    // Adjust the start and end points based on the view matrix (to handle rotated arcs)
    SkV4 devPoints[3];
    transform.mapPoints(localPoints, devPoints, 3);
    // Translate the point relative to the transformed origin
    SkV2 startPoint = {devPoints[0].x - devPoints[2].x, devPoints[0].y - devPoints[2].y};
    SkV2 stopPoint = {devPoints[1].x - devPoints[2].x, devPoints[1].y - devPoints[2].y};
    startPoint = startPoint.normalize();
    stopPoint = stopPoint.normalize();

    // We know the matrix is a similarity here. Detect mirroring which will affect how we
    // should orient the clip planes for arcs.
    const SkM44& m = transform.matrix();
    auto upperLeftDet = m.rc(0,0) * m.rc(1,1) -
                        m.rc(0,1) * m.rc(1,0);
    if (upperLeftDet < 0) {
        std::swap(startPoint, stopPoint);
    }

    // Like a fill without useCenter, butt-cap stroke can be implemented by clipping against
    // radial lines. We treat round caps the same way, but track coverage of circles at the
    // center of the butts.
    // However, in both cases we have to be careful about the half-circle.
    // case. In that case the two radial lines are equal and so that edge gets clipped
    // twice. Since the shared edge goes through the center we fall back on the !useCenter
    // case.
    auto absSweep = SkScalarAbs(sweepAngleRadians);
    bool useCenter = (arc.isWedge() || isStroke) &&
                     !SkScalarNearlyEqual(absSweep, SK_ScalarPI);

    // This makes every point fully inside the plane.
    SkV3 geoClipPlane = {0.f, 0.f, 1.f};
    SkV3 clipPlane0;
    SkV3 clipPlane1;
    SkV2 roundCapPos0 = {0, 0};
    SkV2 roundCapPos1 = {0, 0};
    static constexpr float kIntersection_NoRoundCaps = 1;
    static constexpr float kIntersection_RoundCaps = 2;

    float roundCapRadius = 0;
    // Default to intersection and no round caps.
    float flags = kIntersection_NoRoundCaps;
    // Determine if we need round caps.
    if (isStroke &&
        params.strokeStyle().halfWidth() > 0 &&
        params.strokeStyle().cap() == SkPaint::kRound_Cap) {
        // Compute the cap center points in the normalized space.
        float midRadius = (innerRadius + outerRadius) / (2 * outerRadius);
        roundCapPos0 = startPoint * midRadius;
        roundCapPos1 = stopPoint * midRadius;
        flags = kIntersection_RoundCaps;
        // Compute the cap radius in the normalized space.
        roundCapRadius = (outerRadius - innerRadius) / (2 * outerRadius);
    }

    // Determine clip planes.
    if (useCenter) {
        SkV2 norm0 = {startPoint.y, -startPoint.x};
        SkV2 norm1 = {stopPoint.y, -stopPoint.x};
        // This ensures that norm0 is always the clockwise plane, and norm1 is CCW.
        if (sweepAngleRadians < 0) {
            std::swap(norm0, norm1);
        }
        norm0 = -norm0;
        clipPlane0 = {norm0.x, norm0.y, 0.5f};
        clipPlane1 = {norm1.x, norm1.y, 0.5f};
        if (absSweep > SK_ScalarPI) {
            // Union
            flags = -flags;
        } else {
            // Intersection
            // Highly acute arc. We need to clip the vertices to the perpendicular half-plane.
            if (!isStroke && absSweep < 0.5f*SK_ScalarPI) {
                // We do this clipping in normalized space so use our original local points.
                // Should already be normalized since they're sin/cos.
                SkV2 localNorm0 = {localPoints[0].y, -localPoints[0].x};
                SkV2 localNorm1 = {localPoints[1].y, -localPoints[1].x};
                // This ensures that norm0 is always the clockwise plane, and norm1 is CCW.
                if (sweepAngleRadians < 0) {
                    std::swap(localNorm0, localNorm1);
                }
                // Negate norm0 and compute the perpendicular of the difference
                SkV2 clipNorm = {-localNorm0.y - localNorm1.y, localNorm1.x + localNorm0.x};
                clipNorm = clipNorm.normalize();
                // This should give us 1/2 pixel spacing from the half-plane
                // after transforming from normalized to local to device space.
                float dist = 0.5f / radius / transform.maxScaleFactor();
                geoClipPlane = {clipNorm.x, clipNorm.y, dist};
            }
        }
    } else {
        // We clip to a secant of the original circle, only one clip plane
        startPoint *= radius;
        stopPoint *= radius;
        SkV2 norm = {startPoint.y - stopPoint.y, stopPoint.x - startPoint.x};
        norm = norm.normalize();
        if (sweepAngleRadians > 0) {
            norm = -norm;
        }
        float d = -norm.dot(startPoint) + 0.5f;
        clipPlane0 = {norm.x, norm.y, d};
        clipPlane1 = {0.f, 0.f, 1.f}; // no clipping
    }

    if (isStroke && innerRadius < -SK_ScalarHalf) {
        // Reset the inner radius to render a filled arc instead of a stroked arc, as the stroke
        // width is greater than or equal to the oval's width.
        innerRadius = -SK_ScalarHalf;
        localInnerRadius = 0.f;
    }

    // The inner radius in the vertex data must be specified in normalized space.
    innerRadius = innerRadius / outerRadius;

    vw << localCenter << localOuterRadius << localInnerRadius
       << outerRadius << innerRadius << flags
       << geoClipPlane << clipPlane0 << clipPlane1
       << roundCapPos0 << roundCapPos1 << roundCapRadius
       << 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 CircularArcRenderStep::writeUniformsAndTextures(const DrawParams&,
                                                     PipelineDataGatherer* gatherer) const {
    // All data is uploaded as instance attributes, so no uniforms are needed.
    SkDEBUGCODE(gatherer->checkRewind());
}

}  // namespace skgpu::graphite
