1 // 2 // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // IndexBuffer.cpp: Defines the abstract IndexBuffer class and IndexBufferInterface 8 // class with derivations, classes that perform graphics API agnostic index buffer operations. 9 10 #include "libGLESv2/renderer/d3d/IndexBuffer.h" 11 #include "libGLESv2/renderer/Renderer.h" 12 13 namespace rx 14 { 15 16 unsigned int IndexBuffer::mNextSerial = 1; 17 18 IndexBuffer::IndexBuffer() 19 { 20 updateSerial(); 21 } 22 23 IndexBuffer::~IndexBuffer() 24 { 25 } 26 27 unsigned int IndexBuffer::getSerial() const 28 { 29 return mSerial; 30 } 31 32 void IndexBuffer::updateSerial() 33 { 34 mSerial = mNextSerial++; 35 } 36 37 38 IndexBufferInterface::IndexBufferInterface(Renderer *renderer, bool dynamic) : mRenderer(renderer) 39 { 40 mIndexBuffer = renderer->createIndexBuffer(); 41 42 mDynamic = dynamic; 43 mWritePosition = 0; 44 } 45 46 IndexBufferInterface::~IndexBufferInterface() 47 { 48 if (mIndexBuffer) 49 { 50 delete mIndexBuffer; 51 } 52 } 53 54 GLenum IndexBufferInterface::getIndexType() const 55 { 56 return mIndexBuffer->getIndexType(); 57 } 58 59 unsigned int IndexBufferInterface::getBufferSize() const 60 { 61 return mIndexBuffer->getBufferSize(); 62 } 63 64 unsigned int IndexBufferInterface::getSerial() const 65 { 66 return mIndexBuffer->getSerial(); 67 } 68 69 gl::Error IndexBufferInterface::mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset) 70 { 71 // Protect against integer overflow 72 if (mWritePosition + size < mWritePosition) 73 { 74 return gl::Error(GL_OUT_OF_MEMORY, "Mapping of internal index buffer would cause an integer overflow."); 75 } 76 77 gl::Error error = mIndexBuffer->mapBuffer(mWritePosition, size, outMappedMemory); 78 if (error.isError()) 79 { 80 if (outMappedMemory) 81 { 82 *outMappedMemory = NULL; 83 } 84 return error; 85 } 86 87 if (streamOffset) 88 { 89 *streamOffset = mWritePosition; 90 } 91 92 mWritePosition += size; 93 return gl::Error(GL_NO_ERROR); 94 } 95 96 gl::Error IndexBufferInterface::unmapBuffer() 97 { 98 return mIndexBuffer->unmapBuffer(); 99 } 100 101 IndexBuffer * IndexBufferInterface::getIndexBuffer() const 102 { 103 return mIndexBuffer; 104 } 105 106 unsigned int IndexBufferInterface::getWritePosition() const 107 { 108 return mWritePosition; 109 } 110 111 void IndexBufferInterface::setWritePosition(unsigned int writePosition) 112 { 113 mWritePosition = writePosition; 114 } 115 116 gl::Error IndexBufferInterface::discard() 117 { 118 return mIndexBuffer->discard(); 119 } 120 121 gl::Error IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum indexType) 122 { 123 if (mIndexBuffer->getBufferSize() == 0) 124 { 125 return mIndexBuffer->initialize(bufferSize, indexType, mDynamic); 126 } 127 else 128 { 129 return mIndexBuffer->setSize(bufferSize, indexType); 130 } 131 } 132 133 StreamingIndexBufferInterface::StreamingIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, true) 134 { 135 } 136 137 StreamingIndexBufferInterface::~StreamingIndexBufferInterface() 138 { 139 } 140 141 gl::Error StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType) 142 { 143 unsigned int curBufferSize = getBufferSize(); 144 unsigned int writePos = getWritePosition(); 145 if (size > curBufferSize) 146 { 147 gl::Error error = setBufferSize(std::max(size, 2 * curBufferSize), indexType); 148 if (error.isError()) 149 { 150 return error; 151 } 152 setWritePosition(0); 153 } 154 else if (writePos + size > curBufferSize || writePos + size < writePos) 155 { 156 gl::Error error = discard(); 157 if (error.isError()) 158 { 159 return error; 160 } 161 setWritePosition(0); 162 } 163 164 return gl::Error(GL_NO_ERROR); 165 } 166 167 168 StaticIndexBufferInterface::StaticIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, false) 169 { 170 } 171 172 StaticIndexBufferInterface::~StaticIndexBufferInterface() 173 { 174 } 175 176 gl::Error StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType) 177 { 178 unsigned int curSize = getBufferSize(); 179 if (curSize == 0) 180 { 181 return setBufferSize(size, indexType); 182 } 183 else if (curSize >= size && indexType == getIndexType()) 184 { 185 return gl::Error(GL_NO_ERROR); 186 } 187 else 188 { 189 UNREACHABLE(); 190 return gl::Error(GL_INVALID_OPERATION, "Internal static index buffers can't be resized"); 191 } 192 } 193 194 IndexRangeCache *StaticIndexBufferInterface::getIndexRangeCache() 195 { 196 return &mIndexRangeCache; 197 } 198 199 } 200