1 #include "precompiled.h" 2 // 3 // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style license that can be 5 // found in the LICENSE file. 6 // 7 8 // IndexBuffer.cpp: Defines the abstract IndexBuffer class and IndexBufferInterface 9 // class with derivations, classes that perform graphics API agnostic index buffer operations. 10 11 #include "libGLESv2/renderer/IndexBuffer.h" 12 #include "libGLESv2/renderer/Renderer.h" 13 14 namespace rx 15 { 16 17 unsigned int IndexBuffer::mNextSerial = 1; 18 19 IndexBuffer::IndexBuffer() 20 { 21 updateSerial(); 22 } 23 24 IndexBuffer::~IndexBuffer() 25 { 26 } 27 28 unsigned int IndexBuffer::getSerial() const 29 { 30 return mSerial; 31 } 32 33 void IndexBuffer::updateSerial() 34 { 35 mSerial = mNextSerial++; 36 } 37 38 39 IndexBufferInterface::IndexBufferInterface(Renderer *renderer, bool dynamic) : mRenderer(renderer) 40 { 41 mIndexBuffer = renderer->createIndexBuffer(); 42 43 mDynamic = dynamic; 44 mWritePosition = 0; 45 } 46 47 IndexBufferInterface::~IndexBufferInterface() 48 { 49 if (mIndexBuffer) 50 { 51 delete mIndexBuffer; 52 } 53 } 54 55 GLenum IndexBufferInterface::getIndexType() const 56 { 57 return mIndexBuffer->getIndexType(); 58 } 59 60 unsigned int IndexBufferInterface::getBufferSize() const 61 { 62 return mIndexBuffer->getBufferSize(); 63 } 64 65 unsigned int IndexBufferInterface::getSerial() const 66 { 67 return mIndexBuffer->getSerial(); 68 } 69 70 bool IndexBufferInterface::mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset) 71 { 72 // Protect against integer overflow 73 if (mWritePosition + size < mWritePosition) 74 { 75 return false; 76 } 77 78 if (!mIndexBuffer->mapBuffer(mWritePosition, size, outMappedMemory)) 79 { 80 if (outMappedMemory) 81 { 82 *outMappedMemory = NULL; 83 } 84 return false; 85 } 86 87 if (streamOffset) 88 { 89 *streamOffset = mWritePosition; 90 } 91 92 mWritePosition += size; 93 return true; 94 } 95 96 bool 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 bool IndexBufferInterface::discard() 117 { 118 return mIndexBuffer->discard(); 119 } 120 121 bool 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 bool StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType) 142 { 143 bool result = true; 144 unsigned int curBufferSize = getBufferSize(); 145 unsigned int writePos = getWritePosition(); 146 if (size > curBufferSize) 147 { 148 result = setBufferSize(std::max(size, 2 * curBufferSize), indexType); 149 setWritePosition(0); 150 } 151 else if (writePos + size > curBufferSize || writePos + size < writePos) 152 { 153 if (!discard()) 154 { 155 return false; 156 } 157 setWritePosition(0); 158 } 159 160 return result; 161 } 162 163 164 StaticIndexBufferInterface::StaticIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, false) 165 { 166 } 167 168 StaticIndexBufferInterface::~StaticIndexBufferInterface() 169 { 170 } 171 172 bool StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType) 173 { 174 unsigned int curSize = getBufferSize(); 175 if (curSize == 0) 176 { 177 return setBufferSize(size, indexType); 178 } 179 else if (curSize >= size && indexType == getIndexType()) 180 { 181 return true; 182 } 183 else 184 { 185 ERR("Static index buffers can't be resized"); 186 UNREACHABLE(); 187 return false; 188 } 189 } 190 191 IndexRangeCache *StaticIndexBufferInterface::getIndexRangeCache() 192 { 193 return &mIndexRangeCache; 194 } 195 196 } 197