IndexBuffer.cpp (4994B)
1 // 2 // Copyright 2002 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 "libANGLE/renderer/d3d/IndexBuffer.h" 11 12 #include "libANGLE/Context.h" 13 #include "libANGLE/renderer/d3d/ContextD3D.h" 14 15 namespace rx 16 { 17 18 unsigned int IndexBuffer::mNextSerial = 1; 19 20 IndexBuffer::IndexBuffer() 21 { 22 updateSerial(); 23 } 24 25 IndexBuffer::~IndexBuffer() {} 26 27 unsigned int IndexBuffer::getSerial() const 28 { 29 return mSerial; 30 } 31 32 void IndexBuffer::updateSerial() 33 { 34 mSerial = mNextSerial++; 35 } 36 37 IndexBufferInterface::IndexBufferInterface(BufferFactoryD3D *factory, bool dynamic) 38 { 39 mIndexBuffer = factory->createIndexBuffer(); 40 41 mDynamic = dynamic; 42 mWritePosition = 0; 43 } 44 45 IndexBufferInterface::~IndexBufferInterface() 46 { 47 if (mIndexBuffer) 48 { 49 delete mIndexBuffer; 50 } 51 } 52 53 gl::DrawElementsType IndexBufferInterface::getIndexType() const 54 { 55 return mIndexBuffer->getIndexType(); 56 } 57 58 unsigned int IndexBufferInterface::getBufferSize() const 59 { 60 return mIndexBuffer->getBufferSize(); 61 } 62 63 unsigned int IndexBufferInterface::getSerial() const 64 { 65 return mIndexBuffer->getSerial(); 66 } 67 68 angle::Result IndexBufferInterface::mapBuffer(const gl::Context *context, 69 unsigned int size, 70 void **outMappedMemory, 71 unsigned int *streamOffset) 72 { 73 // Protect against integer overflow 74 bool check = (mWritePosition + size < mWritePosition); 75 ANGLE_CHECK(GetImplAs<ContextD3D>(context), !check, 76 "Mapping of internal index buffer would cause an integer overflow.", 77 GL_OUT_OF_MEMORY); 78 79 angle::Result error = mIndexBuffer->mapBuffer(context, mWritePosition, size, outMappedMemory); 80 if (error == angle::Result::Stop) 81 { 82 if (outMappedMemory) 83 { 84 *outMappedMemory = nullptr; 85 } 86 return error; 87 } 88 89 if (streamOffset) 90 { 91 *streamOffset = mWritePosition; 92 } 93 94 mWritePosition += size; 95 return angle::Result::Continue; 96 } 97 98 angle::Result IndexBufferInterface::unmapBuffer(const gl::Context *context) 99 { 100 return mIndexBuffer->unmapBuffer(context); 101 } 102 103 IndexBuffer *IndexBufferInterface::getIndexBuffer() const 104 { 105 return mIndexBuffer; 106 } 107 108 unsigned int IndexBufferInterface::getWritePosition() const 109 { 110 return mWritePosition; 111 } 112 113 void IndexBufferInterface::setWritePosition(unsigned int writePosition) 114 { 115 mWritePosition = writePosition; 116 } 117 118 angle::Result IndexBufferInterface::discard(const gl::Context *context) 119 { 120 return mIndexBuffer->discard(context); 121 } 122 123 angle::Result IndexBufferInterface::setBufferSize(const gl::Context *context, 124 unsigned int bufferSize, 125 gl::DrawElementsType indexType) 126 { 127 if (mIndexBuffer->getBufferSize() == 0) 128 { 129 return mIndexBuffer->initialize(context, bufferSize, indexType, mDynamic); 130 } 131 else 132 { 133 return mIndexBuffer->setSize(context, bufferSize, indexType); 134 } 135 } 136 137 StreamingIndexBufferInterface::StreamingIndexBufferInterface(BufferFactoryD3D *factory) 138 : IndexBufferInterface(factory, true) 139 {} 140 141 StreamingIndexBufferInterface::~StreamingIndexBufferInterface() {} 142 143 angle::Result StreamingIndexBufferInterface::reserveBufferSpace(const gl::Context *context, 144 unsigned int size, 145 gl::DrawElementsType indexType) 146 { 147 unsigned int curBufferSize = getBufferSize(); 148 unsigned int writePos = getWritePosition(); 149 if (size > curBufferSize) 150 { 151 ANGLE_TRY(setBufferSize(context, std::max(size, 2 * curBufferSize), indexType)); 152 setWritePosition(0); 153 } 154 else if (writePos + size > curBufferSize || writePos + size < writePos) 155 { 156 ANGLE_TRY(discard(context)); 157 setWritePosition(0); 158 } 159 160 return angle::Result::Continue; 161 } 162 163 StaticIndexBufferInterface::StaticIndexBufferInterface(BufferFactoryD3D *factory) 164 : IndexBufferInterface(factory, false) 165 {} 166 167 StaticIndexBufferInterface::~StaticIndexBufferInterface() {} 168 169 angle::Result StaticIndexBufferInterface::reserveBufferSpace(const gl::Context *context, 170 unsigned int size, 171 gl::DrawElementsType indexType) 172 { 173 unsigned int curSize = getBufferSize(); 174 if (curSize == 0) 175 { 176 return setBufferSize(context, size, indexType); 177 } 178 179 ASSERT(curSize >= size && indexType == getIndexType()); 180 return angle::Result::Continue; 181 } 182 183 } // namespace rx