blob: 7fe2a3abe7ca33620b2203d86083f4109cf30e22 [file] [log] [blame]
#include "precompiled.h"
//
// Copyright (c) 2002-2012 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 "libGLESv2/renderer/IndexBuffer.h"
#include "libGLESv2/renderer/Renderer.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(Renderer *renderer, bool dynamic) : mRenderer(renderer)
{
mIndexBuffer = renderer->createIndexBuffer();
mDynamic = dynamic;
mWritePosition = 0;
}
IndexBufferInterface::~IndexBufferInterface()
{
if (mIndexBuffer)
{
delete mIndexBuffer;
}
}
GLenum IndexBufferInterface::getIndexType() const
{
return mIndexBuffer->getIndexType();
}
unsigned int IndexBufferInterface::getBufferSize() const
{
return mIndexBuffer->getBufferSize();
}
unsigned int IndexBufferInterface::getSerial() const
{
return mIndexBuffer->getSerial();
}
bool IndexBufferInterface::mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset)
{
// Protect against integer overflow
if (mWritePosition + size < mWritePosition)
{
return false;
}
if (!mIndexBuffer->mapBuffer(mWritePosition, size, outMappedMemory))
{
if (outMappedMemory)
{
*outMappedMemory = NULL;
}
return false;
}
if (streamOffset)
{
*streamOffset = mWritePosition;
}
mWritePosition += size;
return true;
}
bool IndexBufferInterface::unmapBuffer()
{
return mIndexBuffer->unmapBuffer();
}
IndexBuffer * IndexBufferInterface::getIndexBuffer() const
{
return mIndexBuffer;
}
unsigned int IndexBufferInterface::getWritePosition() const
{
return mWritePosition;
}
void IndexBufferInterface::setWritePosition(unsigned int writePosition)
{
mWritePosition = writePosition;
}
bool IndexBufferInterface::discard()
{
return mIndexBuffer->discard();
}
bool IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum indexType)
{
if (mIndexBuffer->getBufferSize() == 0)
{
return mIndexBuffer->initialize(bufferSize, indexType, mDynamic);
}
else
{
return mIndexBuffer->setSize(bufferSize, indexType);
}
}
StreamingIndexBufferInterface::StreamingIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, true)
{
}
StreamingIndexBufferInterface::~StreamingIndexBufferInterface()
{
}
bool StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
{
bool result = true;
unsigned int curBufferSize = getBufferSize();
unsigned int writePos = getWritePosition();
if (size > curBufferSize)
{
result = setBufferSize(std::max(size, 2 * curBufferSize), indexType);
setWritePosition(0);
}
else if (writePos + size > curBufferSize || writePos + size < writePos)
{
if (!discard())
{
return false;
}
setWritePosition(0);
}
return result;
}
StaticIndexBufferInterface::StaticIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, false)
{
}
StaticIndexBufferInterface::~StaticIndexBufferInterface()
{
}
bool StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
{
unsigned int curSize = getBufferSize();
if (curSize == 0)
{
return setBufferSize(size, indexType);
}
else if (curSize >= size && indexType == getIndexType())
{
return true;
}
else
{
ERR("Static index buffers can't be resized");
UNREACHABLE();
return false;
}
}
IndexRangeCache *StaticIndexBufferInterface::getIndexRangeCache()
{
return &mIndexRangeCache;
}
}