//
// Copyright 2002 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.
//

// VertexBuffer.cpp: Defines the abstract VertexBuffer class and VertexBufferInterface
// class with derivations, classes that perform graphics API agnostic vertex buffer operations.

#include "libANGLE/renderer/d3d/VertexBuffer.h"

#include "common/mathutil.h"
#include "libANGLE/Context.h"
#include "libANGLE/VertexAttribute.h"
#include "libANGLE/renderer/d3d/BufferD3D.h"
#include "libANGLE/renderer/d3d/ContextD3D.h"

namespace rx
{

// VertexBuffer Implementation
unsigned int VertexBuffer::mNextSerial = 1;

VertexBuffer::VertexBuffer() : mRefCount(1)
{
    updateSerial();
}

VertexBuffer::~VertexBuffer() {}

void VertexBuffer::updateSerial()
{
    mSerial = mNextSerial++;
}

unsigned int VertexBuffer::getSerial() const
{
    return mSerial;
}

void VertexBuffer::addRef()
{
    mRefCount++;
}

void VertexBuffer::release()
{
    ASSERT(mRefCount > 0);
    mRefCount--;

    if (mRefCount == 0)
    {
        delete this;
    }
}

// VertexBufferInterface Implementation
VertexBufferInterface::VertexBufferInterface(BufferFactoryD3D *factory, bool dynamic)
    : mFactory(factory), mVertexBuffer(factory->createVertexBuffer()), mDynamic(dynamic)
{}

VertexBufferInterface::~VertexBufferInterface()
{
    if (mVertexBuffer)
    {
        mVertexBuffer->release();
        mVertexBuffer = nullptr;
    }
}

unsigned int VertexBufferInterface::getSerial() const
{
    ASSERT(mVertexBuffer);
    return mVertexBuffer->getSerial();
}

unsigned int VertexBufferInterface::getBufferSize() const
{
    ASSERT(mVertexBuffer);
    return mVertexBuffer->getBufferSize();
}

angle::Result VertexBufferInterface::setBufferSize(const gl::Context *context, unsigned int size)
{
    ASSERT(mVertexBuffer);
    if (mVertexBuffer->getBufferSize() == 0)
    {
        return mVertexBuffer->initialize(context, size, mDynamic);
    }

    return mVertexBuffer->setBufferSize(context, size);
}

angle::Result VertexBufferInterface::getSpaceRequired(const gl::Context *context,
                                                      const gl::VertexAttribute &attrib,
                                                      const gl::VertexBinding &binding,
                                                      size_t count,
                                                      GLsizei instances,
                                                      uint64_t baseInstance,
                                                      unsigned int *spaceInBytesOut) const
{
    unsigned int spaceRequired = 0;
    ANGLE_TRY(mFactory->getVertexSpaceRequired(context, attrib, binding, count, instances,
                                               baseInstance, &spaceRequired));

    // Align to 16-byte boundary
    unsigned int alignedSpaceRequired = roundUpPow2(spaceRequired, 16u);
    ANGLE_CHECK_GL_ALLOC(GetImplAs<ContextD3D>(context), alignedSpaceRequired >= spaceRequired);

    *spaceInBytesOut = alignedSpaceRequired;
    return angle::Result::Continue;
}

angle::Result VertexBufferInterface::discard(const gl::Context *context)
{
    ASSERT(mVertexBuffer);
    return mVertexBuffer->discard(context);
}

VertexBuffer *VertexBufferInterface::getVertexBuffer() const
{
    ASSERT(mVertexBuffer);
    return mVertexBuffer;
}

// StreamingVertexBufferInterface Implementation
StreamingVertexBufferInterface::StreamingVertexBufferInterface(BufferFactoryD3D *factory)
    : VertexBufferInterface(factory, true), mWritePosition(0), mReservedSpace(0)
{}

angle::Result StreamingVertexBufferInterface::initialize(const gl::Context *context,
                                                         std::size_t initialSize)
{
    return setBufferSize(context, static_cast<unsigned int>(initialSize));
}

void StreamingVertexBufferInterface::reset()
{
    if (mVertexBuffer)
    {
        mVertexBuffer->release();
        mVertexBuffer = mFactory->createVertexBuffer();
    }
}

StreamingVertexBufferInterface::~StreamingVertexBufferInterface() {}

angle::Result StreamingVertexBufferInterface::reserveSpace(const gl::Context *context,
                                                           unsigned int size)
{
    unsigned int curBufferSize = getBufferSize();
    if (size > curBufferSize)
    {
        ANGLE_TRY(setBufferSize(context, std::max(size, 3 * curBufferSize / 2)));
        mWritePosition = 0;
    }
    else
    {
        angle::CheckedNumeric<unsigned int> checkedEnd(mWritePosition);
        checkedEnd += size;
        if (!checkedEnd.IsValid() || checkedEnd.ValueOrDie() > curBufferSize)
        {
            ANGLE_TRY(discard(context));
            mWritePosition = 0;
        }
    }

    mReservedSpace = size;
    return angle::Result::Continue;
}

angle::Result StreamingVertexBufferInterface::storeDynamicAttribute(
    const gl::Context *context,
    const gl::VertexAttribute &attrib,
    const gl::VertexBinding &binding,
    gl::VertexAttribType currentValueType,
    size_t start,
    size_t count,
    GLsizei instances,
    uint64_t baseInstance,
    unsigned int *outStreamOffset,
    const uint8_t *sourceData)
{
    unsigned int spaceRequired = 0;
    ANGLE_TRY(
        getSpaceRequired(context, attrib, binding, count, instances, baseInstance, &spaceRequired));

    // Protect against integer overflow
    angle::CheckedNumeric<unsigned int> checkedPosition(mWritePosition);
    checkedPosition += spaceRequired;
    ANGLE_CHECK_GL_ALLOC(
        GetImplAs<ContextD3D>(context),
        checkedPosition.IsValid() && checkedPosition.ValueOrDie() <= getBufferSize());

    mReservedSpace = 0;

    GLuint divisor = binding.getDivisor();
    angle::CheckedNumeric<size_t> checkedCount =
        gl::ComputeVertexBindingElementCount(divisor, count, instances, baseInstance);

    ANGLE_CHECK(GetImplAs<ContextD3D>(context), checkedCount.IsValid(),
                "New vertex buffer size would result in an overflow.", GL_OUT_OF_MEMORY);

    size_t adjustedCount = checkedCount.ValueOrDie();
    ANGLE_TRY(mVertexBuffer->storeVertexAttributes(context, attrib, binding, currentValueType,
                                                   start, adjustedCount, instances, mWritePosition,
                                                   sourceData));

    if (outStreamOffset)
    {
        *outStreamOffset = mWritePosition;
    }

    mWritePosition += spaceRequired;

    return angle::Result::Continue;
}

angle::Result StreamingVertexBufferInterface::reserveVertexSpace(const gl::Context *context,
                                                                 const gl::VertexAttribute &attrib,
                                                                 const gl::VertexBinding &binding,
                                                                 size_t count,
                                                                 GLsizei instances,
                                                                 uint64_t baseInstance)
{
    unsigned int requiredSpace = 0;
    ANGLE_TRY(mFactory->getVertexSpaceRequired(context, attrib, binding, count, instances,
                                               baseInstance, &requiredSpace));

    // Align to 16-byte boundary
    auto alignedRequiredSpace = rx::CheckedRoundUp(requiredSpace, 16u);
    alignedRequiredSpace += mReservedSpace;

    // Protect against integer overflow
    ANGLE_CHECK_GL_ALLOC(GetImplAs<ContextD3D>(context), alignedRequiredSpace.IsValid());

    ANGLE_TRY(reserveSpace(context, alignedRequiredSpace.ValueOrDie()));

    return angle::Result::Continue;
}

// StaticVertexBufferInterface Implementation
StaticVertexBufferInterface::AttributeSignature::AttributeSignature()
    : formatID(angle::FormatID::NONE), stride(0), offset(0)
{}

bool StaticVertexBufferInterface::AttributeSignature::matchesAttribute(
    const gl::VertexAttribute &attrib,
    const gl::VertexBinding &binding) const
{
    size_t attribStride = ComputeVertexAttributeStride(attrib, binding);

    if (formatID != attrib.format->id || static_cast<GLuint>(stride) != attribStride)
    {
        return false;
    }

    size_t attribOffset =
        static_cast<size_t>(ComputeVertexAttributeOffset(attrib, binding) % attribStride);
    return (offset == attribOffset);
}

void StaticVertexBufferInterface::AttributeSignature::set(const gl::VertexAttribute &attrib,
                                                          const gl::VertexBinding &binding)
{
    formatID = attrib.format->id;
    stride   = static_cast<GLuint>(ComputeVertexAttributeStride(attrib, binding));
    offset   = static_cast<size_t>(ComputeVertexAttributeOffset(attrib, binding) %
                                   ComputeVertexAttributeStride(attrib, binding));
}

StaticVertexBufferInterface::StaticVertexBufferInterface(BufferFactoryD3D *factory)
    : VertexBufferInterface(factory, false)
{}

StaticVertexBufferInterface::~StaticVertexBufferInterface() {}

bool StaticVertexBufferInterface::matchesAttribute(const gl::VertexAttribute &attrib,
                                                   const gl::VertexBinding &binding) const
{
    return mSignature.matchesAttribute(attrib, binding);
}

void StaticVertexBufferInterface::setAttribute(const gl::VertexAttribute &attrib,
                                               const gl::VertexBinding &binding)
{
    return mSignature.set(attrib, binding);
}

angle::Result StaticVertexBufferInterface::storeStaticAttribute(const gl::Context *context,
                                                                const gl::VertexAttribute &attrib,
                                                                const gl::VertexBinding &binding,
                                                                size_t start,
                                                                GLsizei count,
                                                                GLsizei instances,
                                                                const uint8_t *sourceData)
{
    unsigned int spaceRequired = 0;
    ANGLE_TRY(getSpaceRequired(context, attrib, binding, count, instances, 0, &spaceRequired));
    ANGLE_TRY(setBufferSize(context, spaceRequired));

    ASSERT(attrib.enabled);
    ANGLE_TRY(mVertexBuffer->storeVertexAttributes(context, attrib, binding,
                                                   gl::VertexAttribType::InvalidEnum, start, count,
                                                   instances, 0, sourceData));

    mSignature.set(attrib, binding);
    mVertexBuffer->hintUnmapResource();
    return angle::Result::Continue;
}

}  // namespace rx
