/*
 * 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/CoverBoundsRenderStep.h"

#include "include/core/SkM44.h"
#include "include/private/SkDebug.h"
#include "include/private/SkEnumBitMask.h"
#include "src/core/SkSLTypeShared.h"
#include "src/core/SkVx.h"
#include "src/gpu/BufferWriter.h"
#include "src/gpu/graphite/Attribute.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/Rect.h"
#include "src/gpu/graphite/geom/Shape.h"
#include "src/gpu/graphite/geom/Transform.h"

namespace skgpu::graphite {

CoverBoundsRenderStep::CoverBoundsRenderStep(Layout layout,
                                             RenderStep::RenderStepID renderStepID,
                                             DepthStencilSettings dsSettings)
        : RenderStep(layout,
                     renderStepID,
                     Flags::kPerformsShading |
                     Flags::kAppendInstances |
                     Flags::kInverseFillsScissor,
                     /*uniforms=*/{},
                     PrimitiveType::kTriangleStrip,
                     dsSettings,
                     /*staticAttrs=*/ {},
                     /*appendAttrs=*/{{{"bounds", VertexAttribType::kFloat4, SkSLType::kFloat4},
                                      {"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}}}) {}

CoverBoundsRenderStep::~CoverBoundsRenderStep() {}

std::string CoverBoundsRenderStep::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 = cover_bounds_vertex_fn("
                                         "float2(sk_VertexID / 2, sk_VertexID % 2), "
                                         "bounds, depth, float3x3(mat0, mat1, mat2), "
                                         "stepLocalCoords);\n";
}

void CoverBoundsRenderStep::writeVertices(DrawWriter* writer,
                                          const DrawParams& params,
                                          uint32_t ssboIndex) const {
    // Each instance is 4 vertices, forming 2 triangles from a single triangle strip, so no indices
    // are needed. sk_VertexID is used to place vertex positions, so no vertex buffer is needed.
    DrawWriter::Instances instances{*writer, {}, {}, 4};

    skvx::float4 bounds;
    if (params.geometry().isShape() && params.geometry().shape().inverted()) {
        // Normally all bounding boxes are sorted such that l<r and t<b. We upload an inverted
        // rectangle [r,b,l,t] when it's an inverse fill to encode that the bounds are already in
        // device space and then the VS will use the inverse of the transform to compute local
        // coordinates.
        bounds = skvx::shuffle</*R*/2, /*B*/3, /*L*/0, /*T*/1>(
                skvx::cast<float>(skvx::int4::Load(&params.scissor())));
    } else {
        bounds = params.geometry().bounds().ltrb();
    }

    // Since the local coords always have Z=0, we can discard the 3rd row and column of the matrix.
    const SkM44& m = params.transform().matrix();
    instances.append(1) << bounds << params.order().depthAsFloat() << ssboIndex
                        << m.rc(0,0) << m.rc(1,0) << m.rc(3,0)
                        << m.rc(0,1) << m.rc(1,1) << m.rc(3,1)
                        << m.rc(0,3) << m.rc(1,3) << m.rc(3,3);
}

void CoverBoundsRenderStep::writeUniformsAndTextures(const DrawParams&,
                                                     PipelineDataGatherer* gatherer) const {
    // All data is uploaded as instance attributes, so no uniforms are needed.
    SkDEBUGCODE(gatherer->checkRewind());
}

}  // namespace skgpu::graphite
