michael@0: #include "precompiled.h" michael@0: // michael@0: // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: // michael@0: michael@0: // IndexBuffer.cpp: Defines the abstract IndexBuffer class and IndexBufferInterface michael@0: // class with derivations, classes that perform graphics API agnostic index buffer operations. michael@0: michael@0: #include "libGLESv2/renderer/IndexBuffer.h" michael@0: #include "libGLESv2/renderer/Renderer.h" michael@0: michael@0: namespace rx michael@0: { michael@0: michael@0: unsigned int IndexBuffer::mNextSerial = 1; michael@0: michael@0: IndexBuffer::IndexBuffer() michael@0: { michael@0: updateSerial(); michael@0: } michael@0: michael@0: IndexBuffer::~IndexBuffer() michael@0: { michael@0: } michael@0: michael@0: unsigned int IndexBuffer::getSerial() const michael@0: { michael@0: return mSerial; michael@0: } michael@0: michael@0: void IndexBuffer::updateSerial() michael@0: { michael@0: mSerial = mNextSerial++; michael@0: } michael@0: michael@0: michael@0: IndexBufferInterface::IndexBufferInterface(Renderer *renderer, bool dynamic) : mRenderer(renderer) michael@0: { michael@0: mIndexBuffer = renderer->createIndexBuffer(); michael@0: michael@0: mDynamic = dynamic; michael@0: mWritePosition = 0; michael@0: } michael@0: michael@0: IndexBufferInterface::~IndexBufferInterface() michael@0: { michael@0: if (mIndexBuffer) michael@0: { michael@0: delete mIndexBuffer; michael@0: } michael@0: } michael@0: michael@0: GLenum IndexBufferInterface::getIndexType() const michael@0: { michael@0: return mIndexBuffer->getIndexType(); michael@0: } michael@0: michael@0: unsigned int IndexBufferInterface::getBufferSize() const michael@0: { michael@0: return mIndexBuffer->getBufferSize(); michael@0: } michael@0: michael@0: unsigned int IndexBufferInterface::getSerial() const michael@0: { michael@0: return mIndexBuffer->getSerial(); michael@0: } michael@0: michael@0: bool IndexBufferInterface::mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset) michael@0: { michael@0: // Protect against integer overflow michael@0: if (mWritePosition + size < mWritePosition) michael@0: { michael@0: return false; michael@0: } michael@0: michael@0: if (!mIndexBuffer->mapBuffer(mWritePosition, size, outMappedMemory)) michael@0: { michael@0: if (outMappedMemory) michael@0: { michael@0: *outMappedMemory = NULL; michael@0: } michael@0: return false; michael@0: } michael@0: michael@0: if (streamOffset) michael@0: { michael@0: *streamOffset = mWritePosition; michael@0: } michael@0: michael@0: mWritePosition += size; michael@0: return true; michael@0: } michael@0: michael@0: bool IndexBufferInterface::unmapBuffer() michael@0: { michael@0: return mIndexBuffer->unmapBuffer(); michael@0: } michael@0: michael@0: IndexBuffer * IndexBufferInterface::getIndexBuffer() const michael@0: { michael@0: return mIndexBuffer; michael@0: } michael@0: michael@0: unsigned int IndexBufferInterface::getWritePosition() const michael@0: { michael@0: return mWritePosition; michael@0: } michael@0: michael@0: void IndexBufferInterface::setWritePosition(unsigned int writePosition) michael@0: { michael@0: mWritePosition = writePosition; michael@0: } michael@0: michael@0: bool IndexBufferInterface::discard() michael@0: { michael@0: return mIndexBuffer->discard(); michael@0: } michael@0: michael@0: bool IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum indexType) michael@0: { michael@0: if (mIndexBuffer->getBufferSize() == 0) michael@0: { michael@0: return mIndexBuffer->initialize(bufferSize, indexType, mDynamic); michael@0: } michael@0: else michael@0: { michael@0: return mIndexBuffer->setSize(bufferSize, indexType); michael@0: } michael@0: } michael@0: michael@0: StreamingIndexBufferInterface::StreamingIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, true) michael@0: { michael@0: } michael@0: michael@0: StreamingIndexBufferInterface::~StreamingIndexBufferInterface() michael@0: { michael@0: } michael@0: michael@0: bool StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType) michael@0: { michael@0: bool result = true; michael@0: unsigned int curBufferSize = getBufferSize(); michael@0: unsigned int writePos = getWritePosition(); michael@0: if (size > curBufferSize) michael@0: { michael@0: result = setBufferSize(std::max(size, 2 * curBufferSize), indexType); michael@0: setWritePosition(0); michael@0: } michael@0: else if (writePos + size > curBufferSize || writePos + size < writePos) michael@0: { michael@0: if (!discard()) michael@0: { michael@0: return false; michael@0: } michael@0: setWritePosition(0); michael@0: } michael@0: michael@0: return result; michael@0: } michael@0: michael@0: michael@0: StaticIndexBufferInterface::StaticIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, false) michael@0: { michael@0: } michael@0: michael@0: StaticIndexBufferInterface::~StaticIndexBufferInterface() michael@0: { michael@0: } michael@0: michael@0: bool StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType) michael@0: { michael@0: unsigned int curSize = getBufferSize(); michael@0: if (curSize == 0) michael@0: { michael@0: return setBufferSize(size, indexType); michael@0: } michael@0: else if (curSize >= size && indexType == getIndexType()) michael@0: { michael@0: return true; michael@0: } michael@0: else michael@0: { michael@0: ERR("Static index buffers can't be resized"); michael@0: UNREACHABLE(); michael@0: return false; michael@0: } michael@0: } michael@0: michael@0: IndexRangeCache *StaticIndexBufferInterface::getIndexRangeCache() michael@0: { michael@0: return &mIndexRangeCache; michael@0: } michael@0: michael@0: } michael@0: