/*
 * Copyright 2026 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/EndCapRenderStep.h"

#include "include/core/SkPath.h"
#include "include/gpu/graphite/Recorder.h"
#include "include/private/SkDebug.h"
#include "src/core/SkSLTypeShared.h"
#include "src/gpu/BufferWriter.h"
#include "src/gpu/graphite/AtlasProvider.h"
#include "src/gpu/graphite/Attribute.h"
#include "src/gpu/graphite/ContextUtils.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/RecorderPriv.h"
#include "src/gpu/graphite/geom/EndCaps.h"
#include "src/gpu/graphite/geom/Geometry.h"
#include "src/gpu/graphite/geom/Transform.h"
#include "src/gpu/graphite/render/CommonDepthStencilSettings.h"
#include "src/gpu/graphite/sparse_strips/AlphaAtlasManager.h"
#include "src/gpu/graphite/sparse_strips/SparseStripsConfig.h"
#include "src/sksl/SkSLString.h"

#include <algorithm>

namespace skgpu::graphite {

EndCapRenderStep::EndCapRenderStep(Layout layout)
        : RenderStep(layout,
                     RenderStepID::kEndCap,
                     Flags::kAppendInstances | Flags::kEmitsCoverage
                                             | Flags::kPerformsShading
                                             | Flags::kOutsetBoundsForAA
                                             | Flags::kHasTextures
                                             | Flags::kNoSelfIntersections,
                     /*uniforms=*/{},
                     PrimitiveType::kTriangleStrip,
                     kDirectDepthLEqualPass,
                     /*vertexAttrs=*/{},
                     /*instanceAttrs=*/
                     {{"tileBounds", VertexAttribType::kFloat4, SkSLType::kFloat4},
                      {"depth", VertexAttribType::kFloat, SkSLType::kFloat},
                      {"ssboIndex", VertexAttribType::kUInt, SkSLType::kUInt},
                      {"mask", VertexAttribType::kUInt, SkSLType::kUInt},
                      {"texPage", VertexAttribType::kUInt, SkSLType::kUInt},
                      {"mat0", VertexAttribType::kFloat3, SkSLType::kFloat3},
                      {"mat1", VertexAttribType::kFloat3, SkSLType::kFloat3},
                      {"mat2", VertexAttribType::kFloat3, SkSLType::kFloat3}},
                     /*storageUniforms=*/{},
                     /*varyings=*/
                     {{{"rectCoord", SkSLType::kFloat2},
                       {"maskIndex", SkSLType::kUInt},
                       {"texPageVarying", SkSLType::kInt}}}) {}

EndCapRenderStep::~EndCapRenderStep() {}

std::string EndCapRenderStep::vertexSkSL(const RootNodesInfo&) const {
    return "float2 position = float2(sk_VertexID < 2 ? tileBounds.x : tileBounds.z,"
                                    "(sk_VertexID % 2) == 0 ? tileBounds.y : tileBounds.w);"
           "float2 rectCoordAttr = float2(sk_VertexID < 2 ? 0.0 : (tileBounds.z - tileBounds.x),"
                                        "(sk_VertexID % 2) == 0 ? 0.0 : (tileBounds.w - "
                                        "tileBounds.y));"
           "float4 devPosition = endcap_vertex_fn(position, rectCoordAttr, depth, mask, texPage, "
                                                 "maskIndex, texPageVarying, rectCoord);"
           "float3x3 invM = float3x3(mat0, mat1, mat2);"
           "float3 localCoords = invM * float3(position, 1.0);"
           "stepLocalCoords = localCoords.xy / localCoords.z;";
}

std::string EndCapRenderStep::texturesAndSamplersSkSL(
        const ResourceBindingRequirements& bindingReqs, int* nextBindingIndex) const {
    std::string result;
    for (int i = 0; i < SparseStripConfig::kMaxTexturePages; ++i) {
        result += EmitSamplerLayout(bindingReqs, nextBindingIndex);
        SkSL::String::appendf(&result, " sampler2D alpha_text_%d;", i);
    }
    return result;
}

const char* EndCapRenderStep::fragmentCoverageSkSL() const {
    return "outputCoverage = endcap_coverage_fn(rectCoord,"
                                               "alpha_text_0,"
                                               "alpha_text_1,"
                                               "maskIndex,"
                                               "texPageVarying);";
}

void EndCapRenderStep::writeVertices(DrawWriter* writer,
                                     StorageContext* /*storageContext*/,
                                     const DrawParams& params,
                                     uint32_t ssboIndex) const {
    SkASSERT(params.geometry().isEndCaps());
    const auto& endCaps = params.geometry().endCaps();

    int32_t start = endCaps.drawStartIndex();
    int32_t end = endCaps.drawEndIndex();
    if (start >= end) {
        return;
    }

    SkM44 invM;
    if (!params.transform().matrix().invert(&invM)) {
        return;
    }

    DrawWriter::Instances instances{*writer, {}, {}, 4};
    instances.reserve(end - start);

    float depth = params.order().depthAsFloat();
    float height = static_cast<float>(SparseStripConfig::kTileHeight);

    const auto& caps = endCaps.caps();
    for (int32_t i = start; i < end; ++i) {
        const auto& cap = caps[i];
        float l = static_cast<float>(cap.fX);
        float t = static_cast<float>(cap.fY);
        float width = static_cast<float>(cap.fWidth);

        float r = l + width;
        float b = t + height;

        instances.append(1) << l << t << r << b << depth << ssboIndex << cap.fAlphaIndex
                            << static_cast<uint32_t>(cap.fTexPage)
                            << invM.rc(0, 0) << invM.rc(1, 0) << invM.rc(3, 0)  // mat0
                            << invM.rc(0, 1) << invM.rc(1, 1) << invM.rc(3, 1)  // mat1
                            << invM.rc(0, 3) << invM.rc(1, 3) << invM.rc(3, 3); // mat2
    }
}

void EndCapRenderStep::writeUniformsAndTextures(const DrawParams& params,
                                                PipelineDataGatherer* gatherer) const {
    SkDEBUGCODE(gatherer->checkRewind());
    SkDEBUGCODE(UniformExpectationsValidator uev(gatherer, this->uniforms());)

    SkASSERT(params.geometry().isEndCaps());
    const auto& proxies = params.geometry().endCaps().proxies();

    for (int i = 0; i < SparseStripConfig::kMaxTexturePages; ++i) {
        SkASSERT(proxies[i] != nullptr);
        gatherer->add(proxies[i], {SkFilterMode::kNearest, SkTileMode::kClamp});
    }
}

}  // namespace skgpu::graphite
