/*
 * 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/base/SkDebug.h"
#include "src/base/SkEnumBitMask.h"
#include "src/base/SkVx.h"
#include "src/core/SkSLTypeShared.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
