/*
 * Copyright 2023 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/compute/ComputeStep.h"

#include "include/private/base/SkAssert.h"

#include <atomic>
#include <unordered_set>

namespace skgpu::graphite {
namespace {

static uint32_t next_id() {
    static std::atomic<int32_t> nextId{0};
    // Not worried about overflow since a Context isn't expected to have that many ComputeSteps.
    // Even if this it wraps around to 0, that ComputeStep will not be in the same Context as the
    // original 0.
    return nextId.fetch_add(1, std::memory_order_relaxed);
}

}  // namespace

ComputeStep::ComputeStep(std::string_view name,
                         WorkgroupSize localDispatchSize,
                         SkSpan<const ResourceDesc> resources,
                         SkSpan<const WorkgroupBufferDesc> workgroupBuffers,
                         Flags baseFlags)
        : fUniqueID(next_id())
        , fFlags(baseFlags)
        , fName(name)
        , fResources(resources.data(), resources.size())
        , fWorkgroupBuffers(workgroupBuffers.data(), workgroupBuffers.size())
        , fLocalDispatchSize(localDispatchSize) {
#ifdef SK_DEBUG
    std::unordered_set<int> slots;
#endif
    for (const ResourceDesc& r : fResources) {
#ifdef SK_DEBUG
        // Validate that slot assignments within a ComputeStep are unique.
        if (r.fFlow == DataFlow::kShared) {
            SkASSERT(r.fSlot > -1);
            SkASSERT(r.fSlot < kMaxComputeDataFlowSlots);
            auto [_, inserted] = slots.insert(r.fSlot);
            SkASSERT(inserted);
        }
#endif  // SK_DEBUG
        switch (r.fFlow) {
            case DataFlow::kVertexOutput:
                SkASSERT(r.fType == ResourceType::kStorageBuffer);
                SkASSERTF(!(fFlags & Flags::kOutputsVertexBuffer),
                          "a ComputeStep cannot produce more than one vertex buffer");
                fFlags |= Flags::kOutputsVertexBuffer;
                break;
            case DataFlow::kIndexOutput:
                SkASSERT(r.fType == ResourceType::kStorageBuffer);
                SkASSERTF(!(fFlags & Flags::kOutputsIndexBuffer),
                          "a ComputeStep cannot produce more than one index buffer");
                fFlags |= Flags::kOutputsIndexBuffer;
                break;
            case DataFlow::kInstanceOutput:
                SkASSERT(r.fType == ResourceType::kStorageBuffer);
                SkASSERTF(!(fFlags & Flags::kOutputsInstanceBuffer),
                          "a ComputeStep cannot produce more than one instance buffer");
                fFlags |= Flags::kOutputsInstanceBuffer;
                break;
            case DataFlow::kIndirectDrawOutput:
                // More than one indirect buffer output cannot be specified.
                SkASSERTF(!(fFlags & Flags::kOutputsIndirectDrawBuffer),
                          "a ComputeStep cannot produce more than indirect buffer");
                fFlags |= Flags::kOutputsIndirectDrawBuffer;
                break;
            default:
                break;
        }
    }
}

void ComputeStep::prepareStorageBuffer(
        const DrawParams&, int, int, const ResourceDesc&, void*, size_t) const {
    SK_ABORT("ComputeSteps that initialize a mapped storage buffer must override "
             "prepareStorageBuffer()");
}

void ComputeStep::prepareUniformBuffer(const DrawParams&,
                                       int,
                                       const ResourceDesc&,
                                       UniformManager*) const {
    SK_ABORT("ComputeSteps that initialize a uniform buffer must override prepareUniformBuffer()");
}

std::string ComputeStep::computeSkSL(const ResourceBindingRequirements&, int) const {
    SK_ABORT("ComputeSteps must override computeSkSL() unless they support native shader source");
    return "";
}

ComputeStep::NativeShaderSource ComputeStep::nativeShaderSource(NativeShaderFormat) const {
    SK_ABORT("ComputeSteps that support native shader source must override nativeShaderSource()");
    return {};
}

size_t ComputeStep::calculateBufferSize(const DrawParams&, int, const ResourceDesc&) const {
    SK_ABORT("ComputeSteps that initialize a storage buffer must override calculateBufferSize()");
    return 0u;
}

std::tuple<SkISize, SkColorType> ComputeStep::calculateTextureParameters(
        const DrawParams&, int resourceIndex, const ResourceDesc&) const {
    SK_ABORT("ComputeStep that initialize a texture must override calculateTextureParameters()");
    return {SkISize::MakeEmpty(), kUnknown_SkColorType};
}

WorkgroupSize ComputeStep::calculateGlobalDispatchSize(const DrawParams&) const {
    SK_ABORT("ComputeSteps must override calculateGlobalDispatchSize() if it participates "
             "in resource creation");
    return WorkgroupSize();
}

}  // namespace skgpu::graphite
