1bdf2d80f459d43f5a6df074431bacf41584f81b7shannon.woods@transgaming.com#include "precompiled.h" 2955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com// 3955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. 4955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com// Use of this source code is governed by a BSD-style license that can be 5955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com// found in the LICENSE file. 6955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com// 7955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 8955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com// IndexBuffer.cpp: Defines the abstract IndexBuffer class and IndexBufferInterface 9955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com// class with derivations, classes that perform graphics API agnostic index buffer operations. 10955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 11955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com#include "libGLESv2/renderer/IndexBuffer.h" 12486d9e9b6b4ed31f66d2624b8e822020fe40a1f7shannon.woods@transgaming.com#include "libGLESv2/renderer/Renderer.h" 13955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 14955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.comnamespace rx 15955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 16955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 172befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.comunsigned int IndexBuffer::mNextSerial = 1; 182befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com 192befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.comIndexBuffer::IndexBuffer() 202befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com{ 212befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com updateSerial(); 222befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com} 232befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com 242befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.comIndexBuffer::~IndexBuffer() 252befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com{ 262befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com} 272befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com 282befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.comunsigned int IndexBuffer::getSerial() const 292befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com{ 302befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com return mSerial; 312befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com} 322befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com 332befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.comvoid IndexBuffer::updateSerial() 342befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com{ 352befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com mSerial = mNextSerial++; 362befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com} 372befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com 382befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com 391e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.comIndexBufferInterface::IndexBufferInterface(Renderer *renderer, bool dynamic) : mRenderer(renderer) 40955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 411e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com mIndexBuffer = renderer->createIndexBuffer(); 42955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 431e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com mDynamic = dynamic; 441e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com mWritePosition = 0; 45955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 46955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 4750cc725131415c0448592104ae2ad5f2079ebc1bdaniel@transgaming.comIndexBufferInterface::~IndexBufferInterface() 48955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 49955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com if (mIndexBuffer) 50955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com { 511e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com delete mIndexBuffer; 52955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com } 53955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 54955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 551e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.comGLenum IndexBufferInterface::getIndexType() const 56955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 571e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return mIndexBuffer->getIndexType(); 58955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 59955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 601e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.comunsigned int IndexBufferInterface::getBufferSize() const 61955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 621e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return mIndexBuffer->getBufferSize(); 63955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 64955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 651e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.comunsigned int IndexBufferInterface::getSerial() const 66955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 671e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return mIndexBuffer->getSerial(); 68955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 69955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 70a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Langbool IndexBufferInterface::mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset) 71955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 72a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang // Protect against integer overflow 73a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang if (mWritePosition + size < mWritePosition) 74a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang { 75a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang return false; 76a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang } 77a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang 781e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com if (!mIndexBuffer->mapBuffer(mWritePosition, size, outMappedMemory)) 79955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com { 80a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang if (outMappedMemory) 81a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang { 82a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang *outMappedMemory = NULL; 83a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang } 84a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang return false; 85955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com } 861e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com 87a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang if (streamOffset) 88a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang { 89a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang *streamOffset = mWritePosition; 90a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang } 911e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com 92a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang mWritePosition += size; 93a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang return true; 94955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 95955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 961e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.combool IndexBufferInterface::unmapBuffer() 97955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 981e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return mIndexBuffer->unmapBuffer(); 99955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 100955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 1011e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.comIndexBuffer * IndexBufferInterface::getIndexBuffer() const 102955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 1031e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return mIndexBuffer; 104955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 105955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 1061e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.comunsigned int IndexBufferInterface::getWritePosition() const 107955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 1081e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return mWritePosition; 1091e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com} 110955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 1111e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.comvoid IndexBufferInterface::setWritePosition(unsigned int writePosition) 1121e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com{ 1131e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com mWritePosition = writePosition; 1141e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com} 115955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 1161e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.combool IndexBufferInterface::discard() 1171e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com{ 1181e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return mIndexBuffer->discard(); 119955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 120955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 1211e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.combool IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum indexType) 122955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 1231e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com if (mIndexBuffer->getBufferSize() == 0) 124955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com { 1251e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return mIndexBuffer->initialize(bufferSize, indexType, mDynamic); 126955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com } 1271e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com else 128955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com { 1291e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return mIndexBuffer->setSize(bufferSize, indexType); 130955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com } 131955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 132955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 1331e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.comStreamingIndexBufferInterface::StreamingIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, true) 134955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 135955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 136955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 1371e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.comStreamingIndexBufferInterface::~StreamingIndexBufferInterface() 138955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 139955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 140955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 1411e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.combool StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType) 142955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 1431e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com bool result = true; 1441e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com unsigned int curBufferSize = getBufferSize(); 145d81cf64c467689b9f7126d0d0064d6387c0adc5dGeoff Lang unsigned int writePos = getWritePosition(); 1461e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com if (size > curBufferSize) 147955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com { 1481e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com result = setBufferSize(std::max(size, 2 * curBufferSize), indexType); 1491e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com setWritePosition(0); 1501e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com } 151d81cf64c467689b9f7126d0d0064d6387c0adc5dGeoff Lang else if (writePos + size > curBufferSize || writePos + size < writePos) 1521e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com { 1531e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com if (!discard()) 154955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com { 1551e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return false; 156955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com } 1571e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com setWritePosition(0); 158955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com } 159955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 1601e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return result; 161955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 162955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 1631e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com 1641e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.comStaticIndexBufferInterface::StaticIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, false) 165955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 1661e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com} 167955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 1681e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.comStaticIndexBufferInterface::~StaticIndexBufferInterface() 1691e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com{ 1701e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com} 171955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 1721e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.combool StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType) 1731e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com{ 1741e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com unsigned int curSize = getBufferSize(); 1751e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com if (curSize == 0) 1761e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com { 1771e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return setBufferSize(size, indexType); 178955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com } 1791e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com else if (curSize >= size && indexType == getIndexType()) 180955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com { 1811e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return true; 1821e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com } 1831e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com else 1841e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com { 1851e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com ERR("Static index buffers can't be resized"); 1861e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com UNREACHABLE(); 1871e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return false; 188955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com } 189955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 190955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 191f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff LangIndexRangeCache *StaticIndexBufferInterface::getIndexRangeCache() 192955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 193f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang return &mIndexRangeCache; 194955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 195955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 196955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 197