/*
 * 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"
#include "src/gpu/graphite/render/CommonDepthStencilSettings.h"

namespace skgpu::graphite {

CoverBoundsRenderStep::CoverBoundsRenderStep(Layout layout,
                                             RenderStep::RenderStepID renderStepID,
                                             StencilSettings stencilSettings)
        : RenderStep(layout,
                     renderStepID,
                     Flags::kPerformsShading | Flags::kNoSelfIntersections
                                             | Flags::kAppendInstances
                                             | Flags::kInverseFillsScissor,
                     /*uniforms=*/{},
                     PrimitiveType::kTriangleStrip,
                     stencilSettings,
                     /*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}}},
                     /*storageUniforms=*/{}) {}

CoverBoundsRenderStep::~CoverBoundsRenderStep() {}

std::unique_ptr<CoverBoundsRenderStep> CoverBoundsRenderStep::NonAAInnerFill(Layout layout) {
    return std::unique_ptr<CoverBoundsRenderStep>(new CoverBoundsRenderStep(
            layout, RenderStepID::kCoverBounds_NonAAFill, /*stencilSettings=*/{}));
}

std::unique_ptr<CoverBoundsRenderStep> CoverBoundsRenderStep::StencilCover(
        Layout layout, bool inverseFill) {
    RenderStepID id = inverseFill ? RenderStepID::kCoverBounds_InverseCover
                                  : RenderStepID::kCoverBounds_RegularCover;
    StencilSettings stencil = inverseFill ? kInverseCoverPass : kRegularCoverPass;
    return std::unique_ptr<CoverBoundsRenderStep>(new CoverBoundsRenderStep(layout, id, stencil));
}

std::string CoverBoundsRenderStep::vertexSkSL(const RootNodesInfo&) 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,
                                          StorageContext* /*storageContext*/,
                                          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
