| // | |
| // 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 |