blob: 423067e67e9fe6e71b035529898601d762d954ac [file] [log] [blame]
//
// 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.
//
// IndexBuffer.cpp: Defines the abstract IndexBuffer class and IndexBufferInterface
// class with derivations, classes that perform graphics API agnostic index buffer operations.
#include "libANGLE/renderer/d3d/IndexBuffer.h"
#include "libANGLE/Context.h"
#include "libANGLE/renderer/d3d/ContextD3D.h"
namespace rx
{
unsigned int IndexBuffer::mNextSerial = 1;
IndexBuffer::IndexBuffer()
{
updateSerial();
}
IndexBuffer::~IndexBuffer() {}
unsigned int IndexBuffer::getSerial() const
{
return mSerial;
}
void IndexBuffer::updateSerial()
{
mSerial = mNextSerial++;
}
IndexBufferInterface::IndexBufferInterface(BufferFactoryD3D *factory, bool dynamic)
{
mIndexBuffer = factory->createIndexBuffer();
mDynamic = dynamic;
mWritePosition = 0;
}
IndexBufferInterface::~IndexBufferInterface()
{
if (mIndexBuffer)
{
delete mIndexBuffer;
}
}
gl::DrawElementsType IndexBufferInterface::getIndexType() const
{
return mIndexBuffer->getIndexType();
}
unsigned int IndexBufferInterface::getBufferSize() const
{
return mIndexBuffer->getBufferSize();
}
unsigned int IndexBufferInterface::getSerial() const
{
return mIndexBuffer->getSerial();
}
angle::Result IndexBufferInterface::mapBuffer(const gl::Context *context,
unsigned int size,
void **outMappedMemory,
unsigned int *streamOffset)
{
// Protect against integer overflow
bool check = (mWritePosition + size < mWritePosition);
ANGLE_CHECK(GetImplAs<ContextD3D>(context), !check,
"Mapping of internal index buffer would cause an integer overflow.",
GL_OUT_OF_MEMORY);
angle::Result error = mIndexBuffer->mapBuffer(context, mWritePosition, size, outMappedMemory);
if (error == angle::Result::Stop)
{
if (outMappedMemory)
{
*outMappedMemory = nullptr;
}
return error;
}
if (streamOffset)
{
*streamOffset = mWritePosition;
}
mWritePosition += size;
return angle::Result::Continue;
}
angle::Result IndexBufferInterface::unmapBuffer(const gl::Context *context)
{
return mIndexBuffer->unmapBuffer(context);
}
IndexBuffer *IndexBufferInterface::getIndexBuffer() const
{
return mIndexBuffer;
}
unsigned int IndexBufferInterface::getWritePosition() const
{
return mWritePosition;
}
void IndexBufferInterface::setWritePosition(unsigned int writePosition)
{
mWritePosition = writePosition;
}
angle::Result IndexBufferInterface::discard(const gl::Context *context)
{
return mIndexBuffer->discard(context);
}
angle::Result IndexBufferInterface::setBufferSize(const gl::Context *context,
unsigned int bufferSize,
gl::DrawElementsType indexType)
{
if (mIndexBuffer->getBufferSize() == 0)
{
return mIndexBuffer->initialize(context, bufferSize, indexType, mDynamic);
}
else
{
return mIndexBuffer->setSize(context, bufferSize, indexType);
}
}
StreamingIndexBufferInterface::StreamingIndexBufferInterface(BufferFactoryD3D *factory)
: IndexBufferInterface(factory, true)
{}
StreamingIndexBufferInterface::~StreamingIndexBufferInterface() {}
angle::Result StreamingIndexBufferInterface::reserveBufferSpace(const gl::Context *context,
unsigned int size,
gl::DrawElementsType indexType)
{
unsigned int curBufferSize = getBufferSize();
unsigned int writePos = getWritePosition();
if (size > curBufferSize)
{
ANGLE_TRY(setBufferSize(context, std::max(size, 2 * curBufferSize), indexType));
setWritePosition(0);
}
else if (writePos + size > curBufferSize || writePos + size < writePos)
{
ANGLE_TRY(discard(context));
setWritePosition(0);
}
return angle::Result::Continue;
}
StaticIndexBufferInterface::StaticIndexBufferInterface(BufferFactoryD3D *factory)
: IndexBufferInterface(factory, false)
{}
StaticIndexBufferInterface::~StaticIndexBufferInterface() {}
angle::Result StaticIndexBufferInterface::reserveBufferSpace(const gl::Context *context,
unsigned int size,
gl::DrawElementsType indexType)
{
unsigned int curSize = getBufferSize();
if (curSize == 0)
{
return setBufferSize(context, size, indexType);
}
ASSERT(curSize >= size && indexType == getIndexType());
return angle::Result::Continue;
}
} // namespace rx