1955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com// 2955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. 3955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com// Use of this source code is governed by a BSD-style license that can be 4955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com// found in the LICENSE file. 5955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com// 6955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 7955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com// IndexBuffer.cpp: Defines the abstract IndexBuffer class and IndexBufferInterface 8955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com// class with derivations, classes that perform graphics API agnostic index buffer operations. 9955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 10c7a4104957aa1f6fa36e4e9cf65d36b699eb05bdBrandon Jones#include "libGLESv2/renderer/d3d/IndexBuffer.h" 11486d9e9b6b4ed31f66d2624b8e822020fe40a1f7shannon.woods@transgaming.com#include "libGLESv2/renderer/Renderer.h" 12955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 13955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.comnamespace rx 14955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 15955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 162befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.comunsigned int IndexBuffer::mNextSerial = 1; 172befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com 182befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.comIndexBuffer::IndexBuffer() 192befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com{ 202befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com updateSerial(); 212befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com} 222befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com 232befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.comIndexBuffer::~IndexBuffer() 242befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com{ 252befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com} 262befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com 272befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.comunsigned int IndexBuffer::getSerial() const 282befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com{ 292befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com return mSerial; 302befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com} 312befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com 322befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.comvoid IndexBuffer::updateSerial() 332befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com{ 342befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com mSerial = mNextSerial++; 352befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com} 362befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com 372befccdf021fe2962f6cfd6f0ffb541954390d78daniel@transgaming.com 381e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.comIndexBufferInterface::IndexBufferInterface(Renderer *renderer, bool dynamic) : mRenderer(renderer) 39955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 401e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com mIndexBuffer = renderer->createIndexBuffer(); 41955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 421e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com mDynamic = dynamic; 431e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com mWritePosition = 0; 44955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 45955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 4650cc725131415c0448592104ae2ad5f2079ebc1bdaniel@transgaming.comIndexBufferInterface::~IndexBufferInterface() 47955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 48955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com if (mIndexBuffer) 49955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com { 501e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com delete mIndexBuffer; 51955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com } 52955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 53955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 541e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.comGLenum IndexBufferInterface::getIndexType() const 55955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 561e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return mIndexBuffer->getIndexType(); 57955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 58955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 591e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.comunsigned int IndexBufferInterface::getBufferSize() const 60955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 611e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return mIndexBuffer->getBufferSize(); 62955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 63955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 641e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.comunsigned int IndexBufferInterface::getSerial() const 65955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 661e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return mIndexBuffer->getSerial(); 67955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 68955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 69c9e69b1941522095a3878d9e1501511ab4722139Geoff Langgl::Error IndexBufferInterface::mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset) 70955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 71a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang // Protect against integer overflow 72a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang if (mWritePosition + size < mWritePosition) 73a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang { 74c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return gl::Error(GL_OUT_OF_MEMORY, "Mapping of internal index buffer would cause an integer overflow."); 75a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang } 76a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang 77c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang gl::Error error = mIndexBuffer->mapBuffer(mWritePosition, size, outMappedMemory); 78c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang if (error.isError()) 79955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com { 80a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang if (outMappedMemory) 81a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang { 82a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang *outMappedMemory = NULL; 83a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang } 84c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return error; 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; 93c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return gl::Error(GL_NO_ERROR); 94955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 95955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 96c9e69b1941522095a3878d9e1501511ab4722139Geoff Langgl::Error 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 116c9e69b1941522095a3878d9e1501511ab4722139Geoff Langgl::Error IndexBufferInterface::discard() 1171e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com{ 1181e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return mIndexBuffer->discard(); 119955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 120955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 121c9e69b1941522095a3878d9e1501511ab4722139Geoff Langgl::Error 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 141c9e69b1941522095a3878d9e1501511ab4722139Geoff Langgl::Error StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType) 142955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 1431e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com unsigned int curBufferSize = getBufferSize(); 144d81cf64c467689b9f7126d0d0064d6387c0adc5dGeoff Lang unsigned int writePos = getWritePosition(); 1451e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com if (size > curBufferSize) 146955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com { 147c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang gl::Error error = setBufferSize(std::max(size, 2 * curBufferSize), indexType); 148c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang if (error.isError()) 149c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang { 150c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return error; 151c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang } 1521e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com setWritePosition(0); 1531e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com } 154d81cf64c467689b9f7126d0d0064d6387c0adc5dGeoff Lang else if (writePos + size > curBufferSize || writePos + size < writePos) 1551e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com { 156c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang gl::Error error = discard(); 157c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang if (error.isError()) 158955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com { 159c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return error; 160955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com } 1611e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com setWritePosition(0); 162955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com } 163955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 164c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return gl::Error(GL_NO_ERROR); 165955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 166955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 1671e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com 1681e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.comStaticIndexBufferInterface::StaticIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, false) 169955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 1701e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com} 171955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 1721e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.comStaticIndexBufferInterface::~StaticIndexBufferInterface() 1731e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com{ 1741e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com} 175955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 176c9e69b1941522095a3878d9e1501511ab4722139Geoff Langgl::Error StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType) 1771e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com{ 1781e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com unsigned int curSize = getBufferSize(); 1791e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com if (curSize == 0) 1801e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com { 1811e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com return setBufferSize(size, indexType); 182955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com } 1831e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com else if (curSize >= size && indexType == getIndexType()) 184955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com { 185c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return gl::Error(GL_NO_ERROR); 1861e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com } 1871e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com else 1881e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com { 1891e3a80411aa79afd2fbe1eeff66b28d2049a5814daniel@transgaming.com UNREACHABLE(); 190c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return gl::Error(GL_INVALID_OPERATION, "Internal static index buffers can't be resized"); 191955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com } 192955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 193955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 194f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff LangIndexRangeCache *StaticIndexBufferInterface::getIndexRangeCache() 195955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com{ 196f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang return &mIndexRangeCache; 197955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 198955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com 199955377ebef0134a7258a8b690853bccb705e9ad3daniel@transgaming.com} 200