//
// Copyright 2024 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// VertexArrayWgpu.cpp:
//    Implements the class methods for VertexArrayWgpu.
//

#include "libANGLE/renderer/wgpu/VertexArrayWgpu.h"

#include <array>

#include "common/unsafe_buffers.h"

#include "common/PackedEnums.h"
#include "common/debug.h"
#include "libANGLE/Error.h"
#include "libANGLE/renderer/wgpu/ContextWgpu.h"
#include "libANGLE/renderer/wgpu/wgpu_utils.h"

namespace rx
{

namespace
{
bool AttributeNeedsStreaming(ContextWgpu *context,
                             const gl::VertexAttribute &attrib,
                             const gl::VertexBinding &binding,
                             const gl::Buffer *bufferGl)
{
    const size_t stride = ComputeVertexAttributeStride(attrib, binding);
    if (stride % 4 != 0)
    {
        return true;
    }

    const size_t typeSize = gl::ComputeVertexAttributeTypeSize(attrib);
    if (stride % typeSize != 0)
    {
        return true;
    }

    const webgpu::Format &vertexFormat = context->getFormat(attrib.format->glInternalFormat);
    if (vertexFormat.vertexLoadRequiresConversion())
    {
        return true;
    }

    if (!bufferGl || bufferGl->getSize() == 0)
    {
        return true;
    }

    return false;
}

template <typename SourceType, typename DestType>
void CopyIndexData(const uint8_t *sourceData, size_t count, uint8_t *destData)
{
    if constexpr (std::is_same<SourceType, DestType>::value)
    {
        ANGLE_UNSAFE_TODO(memcpy(destData, sourceData, sizeof(SourceType) * count));
    }
    else
    {
        for (size_t i = 0; i < count; i++)
        {
            DestType *dst = ANGLE_UNSAFE_TODO(reinterpret_cast<DestType *>(destData) + i);
            const SourceType *src =
                ANGLE_UNSAFE_TODO(reinterpret_cast<const SourceType *>(sourceData) + i);
            *dst                  = static_cast<DestType>(*src);
        }
    }
}
using CopyIndexFunction = void (*)(const uint8_t *sourceData, size_t count, uint8_t *destData);

CopyIndexFunction GetCopyIndexFunction(gl::DrawElementsType sourceType,
                                       gl::DrawElementsType destType)
{
    static_assert(static_cast<size_t>(gl::DrawElementsType::UnsignedByte) == 0);
    static_assert(static_cast<size_t>(gl::DrawElementsType::UnsignedShort) == 1);
    static_assert(static_cast<size_t>(gl::DrawElementsType::UnsignedInt) == 2);
    ASSERT(static_cast<size_t>(sourceType) <= 2);
    ASSERT(static_cast<size_t>(destType) <= 2);
    ASSERT(static_cast<size_t>(destType) >=
           static_cast<size_t>(sourceType));  // Can't copy to a smaller type

    static constexpr std::array<std::array<CopyIndexFunction, 3>, 3> copyFunctions = {{
        {
            CopyIndexData<GLubyte, GLubyte>,
            CopyIndexData<GLubyte, GLushort>,
            CopyIndexData<GLubyte, GLuint>,
        },
        {
            nullptr,
            CopyIndexData<GLushort, GLushort>,
            CopyIndexData<GLushort, GLuint>,
        },
        {
            nullptr,
            nullptr,
            CopyIndexData<GLuint, GLuint>,
        },
    }};

    CopyIndexFunction copyFunction =
        copyFunctions[static_cast<size_t>(sourceType)][static_cast<size_t>(destType)];
    ASSERT(copyFunction != nullptr);
    return copyFunction;
}

}  // namespace

VertexArrayWgpu::VertexArrayWgpu(const gl::VertexArrayState &data,
                                 const gl::VertexArrayBuffers &vertexArrayBuffers)
    : VertexArrayImpl(data, vertexArrayBuffers)
{
    // Pre-initialize mCurrentIndexBuffer to a streaming buffer because no index buffer dirty bit is
    // triggered if our first draw call has no buffer bound.
    mCurrentIndexBuffer = &mStreamingIndexBuffer;
}

angle::Result VertexArrayWgpu::syncState(const gl::Context *context,
                                         const gl::VertexArray::DirtyBits &dirtyBits,
                                         gl::VertexArray::DirtyAttribBitsArray *attribBits,
                                         gl::VertexArray::DirtyBindingBitsArray *bindingBits)
{
    ASSERT(dirtyBits.any());

    ContextWgpu *contextWgpu = GetImplAs<ContextWgpu>(context);

    const std::vector<gl::VertexAttribute> &attribs = mState.getVertexAttributes();
    const std::vector<gl::VertexBinding> &bindings  = mState.getVertexBindings();

    gl::AttributesMask syncedAttributes;

    for (auto iter = dirtyBits.begin(), endIter = dirtyBits.end(); iter != endIter; ++iter)
    {
        size_t dirtyBit = *iter;
        switch (dirtyBit)
        {
            case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER:
            case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA:
                ANGLE_TRY(syncDirtyElementArrayBuffer(contextWgpu));
                contextWgpu->invalidateIndexBuffer();
                break;

#define ANGLE_VERTEX_DIRTY_ATTRIB_FUNC(INDEX)                                     \
    case gl::VertexArray::DIRTY_BIT_ATTRIB_0 + INDEX:                             \
        ANGLE_TRY(syncDirtyAttrib(contextWgpu, attribs[INDEX],                    \
                                  bindings[attribs[INDEX].bindingIndex], INDEX)); \
        (*attribBits)[INDEX].reset();                                             \
        syncedAttributes.set(INDEX);                                              \
        break;

                ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_ATTRIB_FUNC)

#define ANGLE_VERTEX_DIRTY_BINDING_FUNC(INDEX)                                    \
    case gl::VertexArray::DIRTY_BIT_BINDING_0 + INDEX:                            \
        ANGLE_TRY(syncDirtyAttrib(contextWgpu, attribs[INDEX],                    \
                                  bindings[attribs[INDEX].bindingIndex], INDEX)); \
        (*bindingBits)[INDEX].reset();                                            \
        syncedAttributes.set(INDEX);                                              \
        break;

                ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BINDING_FUNC)

#define ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC(INDEX)                                \
    case gl::VertexArray::DIRTY_BIT_BUFFER_DATA_0 + INDEX:                        \
        ANGLE_TRY(syncDirtyAttrib(contextWgpu, attribs[INDEX],                    \
                                  bindings[attribs[INDEX].bindingIndex], INDEX)); \
        syncedAttributes.set(INDEX);                                              \
        break;

                ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC)
            default:
                break;
        }
    }

    for (size_t syncedAttribIndex : syncedAttributes)
    {
        contextWgpu->setVertexAttribute(syncedAttribIndex, mCurrentAttribs[syncedAttribIndex]);
        contextWgpu->invalidateVertexBuffer(syncedAttribIndex);
    }
    return angle::Result::Continue;
}

angle::Result VertexArrayWgpu::syncClientArrays(
    const gl::Context *context,
    const gl::AttributesMask &activeAttributesMask,
    gl::PrimitiveMode mode,
    GLint first,
    GLsizei count,
    GLsizei instanceCount,
    gl::DrawElementsType sourceDrawElementsTypeOrInvalid,
    const void *indices,
    GLint baseVertex,
    bool primitiveRestartEnabled,
    const void **adjustedIndicesPtr,
    uint32_t *indexCountOut)
{
    const DawnProcTable *wgpu = webgpu::GetProcs(context);

    *adjustedIndicesPtr = indices;

    gl::AttributesMask clientAttributesToSync =
        (mState.getClientMemoryAttribsMask() | mForcedStreamingAttributes) &
        mState.getEnabledAttributesMask() & activeAttributesMask;

    gl::DrawElementsType destDrawElementsTypeOrInvalid = sourceDrawElementsTypeOrInvalid;

    IndexDataNeedsStreaming indexDataNeedsStreaming = determineIndexDataNeedsStreaming(
        sourceDrawElementsTypeOrInvalid, count, mode, &destDrawElementsTypeOrInvalid);

    if (!clientAttributesToSync.any() && indexDataNeedsStreaming == IndexDataNeedsStreaming::None)
    {
        return angle::Result::Continue;
    }

    gl::Buffer *elementArrayBuffer = getElementArrayBuffer();
    ContextWgpu *contextWgpu       = webgpu::GetImpl(context);
    webgpu::DeviceHandle device    = webgpu::GetDevice(context);
    const uint8_t *srcIndexData    = static_cast<const uint8_t *>(indices);
    if (elementArrayBuffer)
    {
        BufferWgpu *elementArrayBufferWgpu = GetImplAs<BufferWgpu>(elementArrayBuffer);
        size_t sourceOffset =
            rx::roundDownPow2(reinterpret_cast<size_t>(indices), webgpu::kBufferMapOffsetAlignment);
        ASSERT(sourceOffset < elementArrayBufferWgpu->getBuffer().actualSize());
        size_t mapReadSize = rx::roundUpPow2(
            static_cast<size_t>(elementArrayBufferWgpu->getBuffer().actualSize()) - sourceOffset,
            webgpu::kBufferCopyToBufferAlignment);
        if (!elementArrayBufferWgpu->getBuffer().isMappedForRead())
        {
            ANGLE_TRY(elementArrayBufferWgpu->getBuffer().mapImmediate(
                contextWgpu, WGPUMapMode_Read, sourceOffset, mapReadSize));
        }
        srcIndexData =
            elementArrayBufferWgpu->getBuffer().getMapReadPointer(sourceOffset, mapReadSize);
    }
    uint32_t adjustedCount = calculateAdjustedIndexCount(
        mode, primitiveRestartEnabled, destDrawElementsTypeOrInvalid, count, srcIndexData);

    // If there aren't any client attributes to sync but the adjusted count is 0, that means
    // there no indices outside the primitive restart index, so this is a no-op.
    if (!clientAttributesToSync.any() && adjustedCount == 0)
    {
        return angle::Result::Continue;
    }
    if (indexCountOut)
    {
        *indexCountOut = adjustedCount;
    }

    // If any attributes need to be streamed, we need to know the index range. We also need to know
    // the index range if there is a draw arrays call and we have to stream the index data for it.
    std::optional<gl::IndexRange> indexRange;
    if (clientAttributesToSync.any())
    {
        GLint startVertex  = 0;
        size_t vertexCount = 0;
        ANGLE_TRY(GetVertexRangeInfo(context, first, count, sourceDrawElementsTypeOrInvalid,
                                     indices, baseVertex, &startVertex, &vertexCount));
        indexRange =
            gl::IndexRange(startVertex, static_cast<GLuint>(startVertex + vertexCount - 1));
    }
    else if (indexDataNeedsStreaming != IndexDataNeedsStreaming::None &&
             sourceDrawElementsTypeOrInvalid == gl::DrawElementsType::InvalidEnum)
    {
        indexRange = gl::IndexRange(first, first + count - 1);
    }

    // Pre-compute the total size of all streamed vertex and index data so a single staging buffer
    // can be used
    size_t stagingBufferSize = 0;

    ANGLE_TRY(calculateStagingBufferSize(
        contextWgpu, sourceDrawElementsTypeOrInvalid == destDrawElementsTypeOrInvalid,
        primitiveRestartEnabled, indexDataNeedsStreaming, destDrawElementsTypeOrInvalid,
        adjustedCount, clientAttributesToSync, instanceCount, indexRange, &stagingBufferSize));

    ASSERT(stagingBufferSize % webgpu::kBufferSizeAlignment == 0);
    webgpu::BufferHelper stagingBuffer;
    uint8_t *stagingData              = nullptr;
    size_t currentStagingDataPosition = 0;
    if (stagingBufferSize > 0)
    {
        ASSERT(stagingBufferSize % webgpu::kBufferSizeAlignment == 0);
        ANGLE_TRY(stagingBuffer.initBuffer(wgpu, device, stagingBufferSize,
                                           WGPUBufferUsage_CopySrc | WGPUBufferUsage_MapWrite,
                                           webgpu::MapAtCreation::Yes));
        stagingData = stagingBuffer.getMapWritePointer(0, stagingBufferSize);
    }

    std::vector<BufferCopy> stagingUploads;

    if (indexDataNeedsStreaming != IndexDataNeedsStreaming::None)
    {
        // Indices are streamed to the start of the buffer. Tell the draw call command to use 0 for
        // firstIndex.
        *adjustedIndicesPtr = 0;
        size_t destIndexDataSize =
            static_cast<size_t>(gl::GetDrawElementsTypeSize(destDrawElementsTypeOrInvalid)) *
            adjustedCount;
        size_t destIndexBufferSize =
            rx::roundUpPow2(destIndexDataSize, webgpu::kBufferCopyToBufferAlignment);
        ANGLE_TRY(ensureBufferCreated(context, mStreamingIndexBuffer, destIndexBufferSize, 0,
                                      WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index,
                                      BufferType::IndexBuffer));
        switch (indexDataNeedsStreaming)
        {
            case IndexDataNeedsStreaming::LineLoopStreaming:
                ANGLE_TRY(streamIndicesLineLoop(
                    contextWgpu, sourceDrawElementsTypeOrInvalid, destDrawElementsTypeOrInvalid,
                    count, adjustedCount, indices, primitiveRestartEnabled, stagingData,
                    destIndexBufferSize, indexRange, srcIndexData, &stagingBuffer, &stagingUploads,
                    &currentStagingDataPosition));
                break;
            case IndexDataNeedsStreaming::TriangleFanStreaming:
                UNIMPLEMENTED();
                break;
            case IndexDataNeedsStreaming::NonEmulatedStreaming:
                ANGLE_TRY(streamIndicesDefault(contextWgpu, sourceDrawElementsTypeOrInvalid,
                                               destDrawElementsTypeOrInvalid, mode, count, indices,
                                               stagingData, destIndexBufferSize, &stagingBuffer,
                                               &stagingUploads, &currentStagingDataPosition));
                break;
            default:
                NOTREACHED();
                break;
        }
    }

    const std::vector<gl::VertexAttribute> &attribs = mState.getVertexAttributes();
    const std::vector<gl::VertexBinding> &bindings  = mState.getVertexBindings();
    for (size_t attribIndex : clientAttributesToSync)
    {
        const gl::VertexAttribute &attrib = attribs[attribIndex];
        const gl::VertexBinding &binding  = bindings[attrib.bindingIndex];
        const gl::Buffer *buffer          = getVertexArrayBuffer(attrib.bindingIndex);

        size_t streamedVertexCount = gl::ComputeVertexBindingElementCount(
            binding.getDivisor(), indexRange->vertexCount(), std::max(instanceCount, 1), 0);

        const size_t sourceStride   = ComputeVertexAttributeStride(attrib, binding);
        const size_t sourceTypeSize = gl::ComputeVertexAttributeTypeSize(attrib);

        // Vertices do not apply the 'start' offset when the divisor is non-zero even when doing
        // a non-instanced draw call
        const size_t firstIndex = (binding.getDivisor() == 0) ? indexRange->start() : 0;

        // Attributes using client memory ignore the VERTEX_ATTRIB_BINDING state.
        // https://www.opengl.org/registry/specs/ARB/vertex_attrib_binding.txt
        const uint8_t *inputPointer = static_cast<const uint8_t *>(attrib.pointer);

        webgpu::BufferReadback readbackBuffer;
        if (buffer)
        {
            webgpu::BufferHelper &srcBuffer = webgpu::GetImpl(buffer)->getBuffer();
            size_t sourceVertexDataSize =
                sourceStride * (firstIndex + streamedVertexCount - 1) + sourceTypeSize;

            ANGLE_TRY(srcBuffer.readDataImmediate(
                contextWgpu, 0, reinterpret_cast<uintptr_t>(attrib.pointer) + sourceVertexDataSize,
                webgpu::RenderPassClosureReason::IndexRangeReadback, &readbackBuffer));
            inputPointer = ANGLE_UNSAFE_TODO(readbackBuffer.data +
                                             reinterpret_cast<uintptr_t>(attrib.pointer));
        }

        const webgpu::Format &vertexFormat =
            contextWgpu->getFormat(attrib.format->glInternalFormat);
        size_t destTypeSize = vertexFormat.getActualBufferFormat().pixelBytes;

        VertexCopyFunction copyFunction = vertexFormat.getVertexLoadFunction();
        ASSERT(copyFunction != nullptr);
        ASSERT(stagingData != nullptr);
        copyFunction(ANGLE_UNSAFE_TODO(inputPointer + (sourceStride * firstIndex)), sourceStride,
                     streamedVertexCount,
                     ANGLE_UNSAFE_TODO(stagingData + currentStagingDataPosition));

        size_t copySize = rx::roundUpPow2(streamedVertexCount * destTypeSize,
                                          webgpu::kBufferCopyToBufferAlignment);
        // Pad the streaming buffer with empty data at the beginning to put the vertex data at the
        // same index location. The stride is tightly packed.
        size_t destCopyOffset = firstIndex * destTypeSize;

        ANGLE_TRY(ensureBufferCreated(
            context, mStreamingArrayBuffers[attribIndex], destCopyOffset + copySize, attribIndex,
            WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex, BufferType::ArrayBuffer));

        stagingUploads.push_back({currentStagingDataPosition, &stagingBuffer,
                                  &mStreamingArrayBuffers[attribIndex], destCopyOffset, copySize});

        currentStagingDataPosition += copySize;
    }

    if (stagingBuffer.valid())
    {
        ANGLE_TRY(stagingBuffer.unmap());
    }
    webgpu::CommandEncoderHandle commandEncoder;
    ANGLE_TRY(contextWgpu->getCurrentCommandEncoder(
        webgpu::RenderPassClosureReason::VertexArrayStreaming, &commandEncoder));

    for (const BufferCopy &copy : stagingUploads)
    {
        wgpu->commandEncoderCopyBufferToBuffer(commandEncoder.get(), copy.src->getBuffer().get(),
                                               copy.sourceOffset, copy.dest->getBuffer().get(),
                                               copy.destOffset, copy.size);
    }

    return angle::Result::Continue;
}

angle::Result VertexArrayWgpu::syncDirtyAttrib(ContextWgpu *contextWgpu,
                                               const gl::VertexAttribute &attrib,
                                               const gl::VertexBinding &binding,
                                               size_t attribIndex)
{
    gl::Buffer *bufferGl = getVertexArrayBuffer(attrib.bindingIndex);
    mForcedStreamingAttributes[attribIndex] =
        AttributeNeedsStreaming(contextWgpu, attrib, binding, bufferGl);

    if (attrib.enabled)
    {
        SetBitField(mCurrentAttribs[attribIndex].enabled, true);
        const webgpu::Format &webgpuFormat =
            contextWgpu->getFormat(attrib.format->glInternalFormat);
        SetBitField(mCurrentAttribs[attribIndex].format, webgpuFormat.getActualWgpuVertexFormat());
        SetBitField(mCurrentAttribs[attribIndex].shaderLocation, attribIndex);

        if (!mForcedStreamingAttributes[attribIndex])
        {
            // Data is sourced directly from the array buffer.
            SetBitField(mCurrentAttribs[attribIndex].offset, 0);
            SetBitField(mCurrentAttribs[attribIndex].stride, binding.getStride());

            ASSERT(bufferGl);
            BufferWgpu *bufferWgpu                   = webgpu::GetImpl(bufferGl);
            mCurrentArrayBuffers[attribIndex].buffer = &(bufferWgpu->getBuffer());
            mCurrentArrayBuffers[attribIndex].offset = reinterpret_cast<uintptr_t>(attrib.pointer);
        }
        else
        {
            SetBitField(mCurrentAttribs[attribIndex].offset, 0);
            SetBitField(mCurrentAttribs[attribIndex].stride,
                        webgpuFormat.getActualBufferFormat().pixelBytes);
            mCurrentArrayBuffers[attribIndex].buffer = &mStreamingArrayBuffers[attribIndex];
            mCurrentArrayBuffers[attribIndex].offset = 0;
        }
    }
    else
    {
        ANGLE_UNSAFE_TODO(
            memset(&mCurrentAttribs[attribIndex], 0, sizeof(webgpu::PackedVertexAttribute)));
        mCurrentArrayBuffers[attribIndex].buffer = nullptr;
        mCurrentArrayBuffers[attribIndex].offset = 0;
    }

    return angle::Result::Continue;
}

angle::Result VertexArrayWgpu::syncDirtyElementArrayBuffer(ContextWgpu *contextWgpu)
{
    gl::Buffer *bufferGl = getElementArrayBuffer();
    if (bufferGl)
    {
        BufferWgpu *buffer  = webgpu::GetImpl(bufferGl);
        mCurrentIndexBuffer = &buffer->getBuffer();
    }
    else
    {
        mCurrentIndexBuffer = &mStreamingIndexBuffer;
    }

    return angle::Result::Continue;
}

angle::Result VertexArrayWgpu::ensureBufferCreated(const gl::Context *context,
                                                   webgpu::BufferHelper &buffer,
                                                   size_t size,
                                                   size_t attribIndex,
                                                   WGPUBufferUsage usage,
                                                   BufferType bufferType)
{
    ContextWgpu *contextWgpu = webgpu::GetImpl(context);
    const DawnProcTable *wgpu = webgpu::GetProcs(contextWgpu);
    if (!buffer.valid() || buffer.requestedSize() < size ||
        wgpu->bufferGetUsage(buffer.getBuffer().get()) != usage)
    {
        webgpu::DeviceHandle device = webgpu::GetDevice(context);
        ANGLE_TRY(buffer.initBuffer(wgpu, device, size, usage, webgpu::MapAtCreation::No));

        if (bufferType == BufferType::IndexBuffer)
        {
            contextWgpu->invalidateIndexBuffer();
        }
        else
        {
            ASSERT(bufferType == BufferType::ArrayBuffer);
            contextWgpu->invalidateVertexBuffer(attribIndex);
        }
    }

    if (bufferType == BufferType::IndexBuffer)
    {
        mCurrentIndexBuffer = &buffer;
    }
    return angle::Result::Continue;
}

IndexDataNeedsStreaming VertexArrayWgpu::determineIndexDataNeedsStreaming(
    gl::DrawElementsType sourceDrawElementsTypeOrInvalid,
    GLsizei count,
    gl::PrimitiveMode mode,
    gl::DrawElementsType *destDrawElementsTypeOrInvalidOut)
{
    if (mode == gl::PrimitiveMode::LineLoop)
    {
        // Promote 8-bit indices to 16-bit indices
        *destDrawElementsTypeOrInvalidOut =
            calculateDrawElementsType(sourceDrawElementsTypeOrInvalid, count);
        return IndexDataNeedsStreaming::LineLoopStreaming;
    }
    else if (mode == gl::PrimitiveMode::TriangleFan)
    {
        *destDrawElementsTypeOrInvalidOut =
            calculateDrawElementsType(sourceDrawElementsTypeOrInvalid, count);
        return IndexDataNeedsStreaming::TriangleFanStreaming;
    }
    else if (sourceDrawElementsTypeOrInvalid != gl::DrawElementsType::InvalidEnum &&
             !getElementArrayBuffer())
    {
        // Index data needs to be uploaded to the GPU
        *destDrawElementsTypeOrInvalidOut =
            calculateDrawElementsType(sourceDrawElementsTypeOrInvalid, count);
        return IndexDataNeedsStreaming::NonEmulatedStreaming;
    }
    return IndexDataNeedsStreaming::None;
}

uint32_t VertexArrayWgpu::calculateAdjustedIndexCount(
    gl::PrimitiveMode mode,
    bool primitiveRestartEnabled,
    gl::DrawElementsType destDrawElementsTypeOrInvalid,
    GLsizei count,
    const uint8_t *srcIndexData)
{
    if (mode == gl::PrimitiveMode::LineLoop)
    {
        if (primitiveRestartEnabled)
        {
            return GetLineLoopWithRestartIndexCount(destDrawElementsTypeOrInvalid, count,
                                                    srcIndexData);
        }
        return count + 1;
    }
    else if (mode == gl::PrimitiveMode::TriangleFan)
    {
        // TODO(crbug.com/401499251): implement helper to calculate the primitive restart count for
        // triangle fans emulation.
        if (primitiveRestartEnabled)
        {
            UNIMPLEMENTED();
            return count;
        }
        return 3 * (count - 2);
    }
    return count;
}

angle::Result VertexArrayWgpu::calculateStagingBufferSize(
    ContextWgpu *contextWgpu,
    bool srcDestDrawElementsTypeEqual,
    bool primitiveRestartEnabled,
    IndexDataNeedsStreaming indexDataNeedsStreaming,
    gl::DrawElementsType destDrawElementsTypeOrInvalid,
    GLsizei adjustedCountForStreamedIndices,
    gl::AttributesMask clientAttributesToSync,
    GLsizei instanceCount,
    std::optional<gl::IndexRange> indexRange,
    size_t *stagingBufferSizeOut)
{
    if (indexDataNeedsStreaming != IndexDataNeedsStreaming::None)
    {
        size_t destIndexUnitSize =
            static_cast<size_t>(gl::GetDrawElementsTypeSize(destDrawElementsTypeOrInvalid));
        size_t destIndexDataSize = destIndexUnitSize * adjustedCountForStreamedIndices;
        // Allocating staging buffer space for indices is only needed when there is no source index
        // buffer or index data conversion is needed
        if (primitiveRestartEnabled || !getElementArrayBuffer() || !srcDestDrawElementsTypeEqual)
        {
            *stagingBufferSizeOut +=
                rx::roundUpPow2(destIndexDataSize, webgpu::kBufferCopyToBufferAlignment);
        }
    }

    const std::vector<gl::VertexAttribute> &attribs = mState.getVertexAttributes();
    const std::vector<gl::VertexBinding> &bindings  = mState.getVertexBindings();

    if (clientAttributesToSync.any())
    {
        for (size_t attribIndex : clientAttributesToSync)
        {
            const gl::VertexAttribute &attrib = attribs[attribIndex];
            const gl::VertexBinding &binding  = bindings[attrib.bindingIndex];

            size_t elementCount = gl::ComputeVertexBindingElementCount(
                binding.getDivisor(), indexRange->vertexCount(), std::max(instanceCount, 1), 0);

            const webgpu::Format &vertexFormat =
                contextWgpu->getFormat(attrib.format->glInternalFormat);
            size_t destTypeSize = vertexFormat.getActualBufferFormat().pixelBytes;
            ASSERT(destTypeSize > 0);

            size_t attribSize = destTypeSize * elementCount;
            *stagingBufferSizeOut +=
                rx::roundUpPow2(attribSize, webgpu::kBufferCopyToBufferAlignment);
        }
    }

    if (*stagingBufferSizeOut > contextWgpu->getDisplay()->getLimitsWgpu().maxBufferSize)
    {
        ERR() << "Staging buffer size of " << stagingBufferSizeOut
              << " in sync client arrays is larger than the max buffer size "
              << contextWgpu->getDisplay()->getLimitsWgpu().maxBufferSize;
        return angle::Result::Stop;
    }
    return angle::Result::Continue;
}

gl::DrawElementsType VertexArrayWgpu::calculateDrawElementsType(
    gl::DrawElementsType sourceDrawElementsTypeOrInvalid,
    GLsizei count)
{
    if (sourceDrawElementsTypeOrInvalid == gl::DrawElementsType::UnsignedByte)
    {
        // Promote 8-bit indices to 16-bit indices
        return gl::DrawElementsType::UnsignedShort;
    }
    // Index data will always need streaming for line loop mode regardless of what type of draw
    // call it is.
    else if (sourceDrawElementsTypeOrInvalid == gl::DrawElementsType::InvalidEnum)
    {
        // Line loop draw array calls are emulated via indexed draw calls, so an index type must
        // be set.
        if (count >= std::numeric_limits<unsigned short>::max())
        {
            return gl::DrawElementsType::UnsignedInt;
        }
        return gl::DrawElementsType::UnsignedShort;
    }
    return sourceDrawElementsTypeOrInvalid;
}

angle::Result VertexArrayWgpu::streamIndicesLineLoop(
    ContextWgpu *contextWgpu,
    gl::DrawElementsType sourceDrawElementsTypeOrInvalid,
    gl::DrawElementsType destDrawElementsTypeOrInvalid,
    GLsizei count,
    GLsizei adjustedCount,
    const void *indices,
    bool primitiveRestartEnabled,
    uint8_t *stagingData,
    size_t destIndexBufferSize,
    std::optional<gl::IndexRange> indexRange,
    const uint8_t *srcIndexData,
    webgpu::BufferHelper *stagingBufferPtr,
    std::vector<BufferCopy> *stagingUploadsOut,
    size_t *currentStagingDataPositionOut)
{
    size_t destIndexUnitSize =
        static_cast<size_t>(gl::GetDrawElementsTypeSize(destDrawElementsTypeOrInvalid));
    gl::Buffer *elementArrayBuffer = getElementArrayBuffer();
    // TODO(anglebug.com/401226623): Don't use the staging buffer when the adjustedCount for
    // primitive restarts is count + 1.
    if (primitiveRestartEnabled)
    {
        rx::StreamEmulatedLineLoopIndices(destDrawElementsTypeOrInvalid, count, srcIndexData,
                                          stagingData,
                                          /* shouldConvertUint8= */ true);
        if (elementArrayBuffer)
        {
            BufferWgpu *elementArrayBufferWgpu = GetImplAs<BufferWgpu>(elementArrayBuffer);
            ANGLE_TRY(elementArrayBufferWgpu->getBuffer().unmap());
        }
        stagingUploadsOut->push_back({*currentStagingDataPositionOut, stagingBufferPtr,
                                      &mStreamingIndexBuffer, 0, destIndexBufferSize});
    }
    else if (sourceDrawElementsTypeOrInvalid == destDrawElementsTypeOrInvalid && elementArrayBuffer)
    {
        // Use the element array buffer as the source for the new streaming index buffer. This
        // condition is only hit when an indexed draw call has an element array buffer and is
        // trying to draw line loops.

        // When using an element array buffer, 'indices' is an offset to the first element.
        size_t sourceOffset                = reinterpret_cast<size_t>(indices);
        BufferWgpu *elementArrayBufferWgpu = GetImplAs<BufferWgpu>(elementArrayBuffer);
        webgpu::BufferHelper *sourceBuffer = &elementArrayBufferWgpu->getBuffer();

        size_t copySize =
            rx::roundUpPow2(destIndexUnitSize * count, webgpu::kBufferCopyToBufferAlignment);
        stagingUploadsOut->push_back(
            {sourceOffset, sourceBuffer, &mStreamingIndexBuffer, 0, copySize});

        // Emulate line loops with an additional copy of the first index at the end of the
        // buffer
        size_t lastOffset = copySize;
        stagingUploadsOut->push_back(
            {sourceOffset, sourceBuffer, &mStreamingIndexBuffer, lastOffset,
             rx::roundUpPow2(destIndexUnitSize, webgpu::kBufferCopyToBufferAlignment)});
    }
    // Handle emulating line loop for draw arrays calls.
    else if (sourceDrawElementsTypeOrInvalid == gl::DrawElementsType::InvalidEnum)
    {
        ASSERT(destDrawElementsTypeOrInvalid != gl::DrawElementsType::InvalidEnum);
        uint32_t clampedVertexCount = gl::clampCast<uint32_t>(indexRange->vertexCount());
        uint32_t startVertex        = static_cast<uint32_t>(indexRange->start());
        size_t index                = *currentStagingDataPositionOut;
        for (uint32_t i = 0; i < clampedVertexCount; i++)
        {
            uint32_t copyData = startVertex + i;
            ANGLE_UNSAFE_TODO(memcpy(stagingData + index, &copyData, destIndexUnitSize));
            index += destIndexUnitSize;
        }
        ANGLE_UNSAFE_TODO(
            memcpy(stagingData + *currentStagingDataPositionOut + destIndexUnitSize * count,
                   &startVertex, destIndexUnitSize));

        size_t copySize = destIndexBufferSize;
        stagingUploadsOut->push_back({*currentStagingDataPositionOut, stagingBufferPtr,
                                      &mStreamingIndexBuffer, 0, copySize});
        *currentStagingDataPositionOut += copySize;
    }
    else
    {
        ANGLE_TRY(streamIndicesDefault(
            contextWgpu, sourceDrawElementsTypeOrInvalid, destDrawElementsTypeOrInvalid,
            gl::PrimitiveMode::LineLoop, count, indices, stagingData, destIndexBufferSize,
            stagingBufferPtr, stagingUploadsOut, currentStagingDataPositionOut));
    }
    return angle::Result::Continue;
}

angle::Result VertexArrayWgpu::streamIndicesDefault(
    ContextWgpu *contextWgpu,
    gl::DrawElementsType sourceDrawElementsTypeOrInvalid,
    gl::DrawElementsType destDrawElementsTypeOrInvalid,
    gl::PrimitiveMode mode,
    GLsizei count,
    const void *indices,
    uint8_t *stagingData,
    size_t destIndexBufferSize,
    webgpu::BufferHelper *stagingBufferPtr,
    std::vector<BufferCopy> *stagingUploadsOut,
    size_t *currentStagingDataPositionOut)
{
    size_t destIndexUnitSize =
        static_cast<size_t>(gl::GetDrawElementsTypeSize(destDrawElementsTypeOrInvalid));

    webgpu::BufferReadback readbackBuffer;
    const uint8_t *srcIndexData = static_cast<const uint8_t *>(indices);
    if (getElementArrayBuffer())
    {
        webgpu::BufferHelper &srcBuffer = webgpu::GetImpl(getElementArrayBuffer())->getBuffer();

        const GLuint srcIndexTypeSize =
            gl::GetDrawElementsTypeSize(sourceDrawElementsTypeOrInvalid);
        const size_t srcIndexOffset = reinterpret_cast<uintptr_t>(indices);

        ANGLE_TRY(srcBuffer.readDataImmediate(contextWgpu, srcIndexOffset, count * srcIndexTypeSize,
                                              webgpu::RenderPassClosureReason::IndexRangeReadback,
                                              &readbackBuffer));
        srcIndexData = readbackBuffer.data;
    }

    CopyIndexFunction indexCopyFunction =
        GetCopyIndexFunction(sourceDrawElementsTypeOrInvalid, destDrawElementsTypeOrInvalid);
    ASSERT(stagingData != nullptr);
    indexCopyFunction(srcIndexData, count,
                      ANGLE_UNSAFE_TODO(stagingData + *currentStagingDataPositionOut));

    if (mode == gl::PrimitiveMode::LineLoop)
    {
        indexCopyFunction(srcIndexData, count,
                          ANGLE_UNSAFE_TODO(stagingData + *currentStagingDataPositionOut +
                                            (destIndexUnitSize * count)));
    }

    size_t copySize = destIndexBufferSize;
    stagingUploadsOut->push_back(
        {*currentStagingDataPositionOut, stagingBufferPtr, &mStreamingIndexBuffer, 0, copySize});
    *currentStagingDataPositionOut += copySize;
    return angle::Result::Continue;
}

}  // namespace rx
