/*
 * 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 "src/core/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
