//
// 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,
                                                      unsigned int *spaceInBytesOut) const
{
    unsigned int spaceRequired = 0;
    ANGLE_TRY(mFactory->getVertexSpaceRequired(context, attrib, binding, count, instances,
                                               &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 if (mWritePosition + size > 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,
    GLint start,
    size_t count,
    GLsizei instances,
    unsigned int *outStreamOffset,
    const uint8_t *sourceData)
{
    unsigned int spaceRequired = 0;
    ANGLE_TRY(getSpaceRequired(context, attrib, binding, count, instances, &spaceRequired));

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

    mReservedSpace = 0;

    ANGLE_TRY(mVertexBuffer->storeVertexAttributes(context, attrib, binding, currentValueType,
                                                   start, count, 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)
{
    unsigned int requiredSpace = 0;
    ANGLE_TRY(mFactory->getVertexSpaceRequired(context, attrib, binding, count, instances,
                                               &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;
    offset = 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,
                                                                GLint start,
                                                                GLsizei count,
                                                                GLsizei instances,
                                                                const uint8_t *sourceData)
{
    unsigned int spaceRequired = 0;
    ANGLE_TRY(getSpaceRequired(context, attrib, binding, count, instances, &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
