blob: e2e307dcb6549672489b1b58071523fce07e983b [file] [log] [blame]
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +00001//
daniel@transgaming.comf6549452012-01-27 15:39:08 +00002// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
daniel@transgaming.com8fd34bd2011-02-18 02:52:14 +00007// IndexDataManager.cpp: Defines the IndexDataManager, a class that
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +00008// runs the Buffer translation process for index buffers.
9
daniel@transgaming.com8fd34bd2011-02-18 02:52:14 +000010#include "libGLESv2/IndexDataManager.h"
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000011
12#include "common/debug.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000013
14#include "libGLESv2/Buffer.h"
daniel@transgaming.com81655a72010-05-20 19:18:17 +000015#include "libGLESv2/mathutil.h"
daniel@transgaming.com37b141e2011-01-08 05:46:13 +000016#include "libGLESv2/main.h"
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000017
18namespace
19{
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +000020 enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) };
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000021}
22
23namespace gl
24{
jbauman@chromium.orgd8f3faa2011-09-02 01:10:47 +000025unsigned int IndexBuffer::mCurrentSerial = 1;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000026
daniel@transgaming.com83921382011-01-08 05:46:00 +000027IndexDataManager::IndexDataManager(Context *context, IDirect3DDevice9 *device) : mDevice(device)
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000028{
daniel@transgaming.com83921382011-01-08 05:46:00 +000029 mStreamingBufferShort = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX16);
daniel@transgaming.com81655a72010-05-20 19:18:17 +000030
daniel@transgaming.com83921382011-01-08 05:46:00 +000031 if (context->supports32bitIndices())
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +000032 {
daniel@transgaming.com83921382011-01-08 05:46:00 +000033 mStreamingBufferInt = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX32);
daniel@transgaming.com72b9e182011-04-13 14:58:33 +000034
35 if (!mStreamingBufferInt)
36 {
37 // Don't leave it in a half-initialized state
38 delete mStreamingBufferShort;
39 mStreamingBufferShort = NULL;
40 }
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +000041 }
42 else
43 {
daniel@transgaming.com83921382011-01-08 05:46:00 +000044 mStreamingBufferInt = NULL;
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +000045 }
daniel@transgaming.com72b9e182011-04-13 14:58:33 +000046
47 if (!mStreamingBufferShort)
48 {
49 ERR("Failed to allocate the streaming index buffer(s).");
50 }
daniel@transgaming.comf6549452012-01-27 15:39:08 +000051
52 mCountingBuffer = NULL;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000053}
54
55IndexDataManager::~IndexDataManager()
56{
daniel@transgaming.com83921382011-01-08 05:46:00 +000057 delete mStreamingBufferShort;
58 delete mStreamingBufferInt;
daniel@transgaming.comf6549452012-01-27 15:39:08 +000059 delete mCountingBuffer;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000060}
61
daniel@transgaming.com83921382011-01-08 05:46:00 +000062void convertIndices(GLenum type, const void *input, GLsizei count, void *output)
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000063{
daniel@transgaming.com83921382011-01-08 05:46:00 +000064 if (type == GL_UNSIGNED_BYTE)
65 {
66 const GLubyte *in = static_cast<const GLubyte*>(input);
67 GLushort *out = static_cast<GLushort*>(output);
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000068
daniel@transgaming.com83921382011-01-08 05:46:00 +000069 for (GLsizei i = 0; i < count; i++)
70 {
71 out[i] = in[i];
72 }
73 }
74 else if (type == GL_UNSIGNED_INT)
75 {
76 memcpy(output, input, count * sizeof(GLuint));
77 }
78 else if (type == GL_UNSIGNED_SHORT)
79 {
80 memcpy(output, input, count * sizeof(GLushort));
81 }
82 else UNREACHABLE();
83}
84
85template <class IndexType>
86void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000087{
daniel@transgaming.com83921382011-01-08 05:46:00 +000088 *minIndex = indices[0];
89 *maxIndex = indices[0];
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000090
91 for (GLsizei i = 0; i < count; i++)
92 {
daniel@transgaming.com83921382011-01-08 05:46:00 +000093 if (*minIndex > indices[i]) *minIndex = indices[i];
94 if (*maxIndex < indices[i]) *maxIndex = indices[i];
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000095 }
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000096}
97
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +000098void computeRange(GLenum type, const GLvoid *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +000099{
daniel@transgaming.com83921382011-01-08 05:46:00 +0000100 if (type == GL_UNSIGNED_BYTE)
daniel@transgaming.com41d8dd82010-05-12 03:45:03 +0000101 {
daniel@transgaming.com83921382011-01-08 05:46:00 +0000102 computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);
103 }
104 else if (type == GL_UNSIGNED_INT)
105 {
106 computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex);
107 }
108 else if (type == GL_UNSIGNED_SHORT)
109 {
110 computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);
111 }
112 else UNREACHABLE();
113}
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000114
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +0000115GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
daniel@transgaming.com83921382011-01-08 05:46:00 +0000116{
daniel@transgaming.com72b9e182011-04-13 14:58:33 +0000117 if (!mStreamingBufferShort)
118 {
119 return GL_OUT_OF_MEMORY;
120 }
121
daniel@transgaming.com83921382011-01-08 05:46:00 +0000122 D3DFORMAT format = (type == GL_UNSIGNED_INT) ? D3DFMT_INDEX32 : D3DFMT_INDEX16;
123 intptr_t offset = reinterpret_cast<intptr_t>(indices);
124 bool alignedOffset = false;
125
126 if (buffer != NULL)
127 {
128 switch (type)
129 {
130 case GL_UNSIGNED_BYTE: alignedOffset = (offset % sizeof(GLubyte) == 0); break;
131 case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break;
132 case GL_UNSIGNED_INT: alignedOffset = (offset % sizeof(GLuint) == 0); break;
133 default: UNREACHABLE(); alignedOffset = false;
134 }
135
136 if (typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))
daniel@transgaming.com41d8dd82010-05-12 03:45:03 +0000137 {
138 return GL_INVALID_OPERATION;
139 }
140
daniel@transgaming.com83921382011-01-08 05:46:00 +0000141 indices = static_cast<const GLubyte*>(buffer->data()) + offset;
daniel@transgaming.com41d8dd82010-05-12 03:45:03 +0000142 }
143
daniel@transgaming.com83921382011-01-08 05:46:00 +0000144 StreamingIndexBuffer *streamingBuffer = (type == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000145
daniel@transgaming.com78624ca2011-04-22 04:17:57 +0000146 StaticIndexBuffer *staticBuffer = buffer ? buffer->getStaticIndexBuffer() : NULL;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000147 IndexBuffer *indexBuffer = streamingBuffer;
148 UINT streamOffset = 0;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000149
daniel@transgaming.com83921382011-01-08 05:46:00 +0000150 if (staticBuffer && staticBuffer->lookupType(type) && alignedOffset)
apatrick@chromium.orgf99fbb72010-11-16 01:57:05 +0000151 {
daniel@transgaming.com83921382011-01-08 05:46:00 +0000152 indexBuffer = staticBuffer;
153 streamOffset = staticBuffer->lookupRange(offset, count, &translated->minIndex, &translated->maxIndex);
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000154
daniel@transgaming.com83921382011-01-08 05:46:00 +0000155 if (streamOffset == -1)
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +0000156 {
daniel@transgaming.com83921382011-01-08 05:46:00 +0000157 streamOffset = (offset / typeSize(type)) * indexSize(format);
158 computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
159 staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset);
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +0000160 }
161 }
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000162 else
163 {
daniel@transgaming.com83921382011-01-08 05:46:00 +0000164 int convertCount = count;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000165
daniel@transgaming.com83921382011-01-08 05:46:00 +0000166 if (staticBuffer)
167 {
168 if (staticBuffer->size() == 0 && alignedOffset)
169 {
170 indexBuffer = staticBuffer;
171 convertCount = buffer->size() / typeSize(type);
172 }
173 else
174 {
175 buffer->invalidateStaticData();
176 staticBuffer = NULL;
177 }
178 }
179
daniel@transgaming.com5ee2ad02011-01-08 05:46:20 +0000180 void *output = NULL;
181
182 if (indexBuffer)
183 {
184 indexBuffer->reserveSpace(convertCount * indexSize(format), type);
185 output = indexBuffer->map(indexSize(format) * convertCount, &streamOffset);
186 }
187
daniel@transgaming.com83921382011-01-08 05:46:00 +0000188 if (output == NULL)
189 {
190 ERR("Failed to map index buffer.");
191 return GL_OUT_OF_MEMORY;
192 }
193
194 convertIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output);
195 indexBuffer->unmap();
196
197 computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
198
199 if (staticBuffer)
200 {
201 streamOffset = (offset / typeSize(type)) * indexSize(format);
202 staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset);
203 }
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000204 }
205
daniel@transgaming.com83921382011-01-08 05:46:00 +0000206 translated->indexBuffer = indexBuffer->getBuffer();
jbauman@chromium.orgd8f3faa2011-09-02 01:10:47 +0000207 translated->serial = indexBuffer->getSerial();
daniel@transgaming.com83921382011-01-08 05:46:00 +0000208 translated->startIndex = streamOffset / indexSize(format);
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000209
daniel@transgaming.com78624ca2011-04-22 04:17:57 +0000210 if (buffer)
211 {
212 buffer->promoteStaticUsage(count * typeSize(type));
213 }
214
daniel@transgaming.com41d8dd82010-05-12 03:45:03 +0000215 return GL_NO_ERROR;
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000216}
217
daniel@transgaming.com83921382011-01-08 05:46:00 +0000218std::size_t IndexDataManager::indexSize(D3DFORMAT format) const
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000219{
daniel@transgaming.com83921382011-01-08 05:46:00 +0000220 return (format == D3DFMT_INDEX32) ? sizeof(unsigned int) : sizeof(unsigned short);
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +0000221}
222
daniel@transgaming.com41d8dd82010-05-12 03:45:03 +0000223std::size_t IndexDataManager::typeSize(GLenum type) const
224{
225 switch (type)
226 {
daniel@transgaming.com83921382011-01-08 05:46:00 +0000227 case GL_UNSIGNED_INT: return sizeof(GLuint);
daniel@transgaming.com41d8dd82010-05-12 03:45:03 +0000228 case GL_UNSIGNED_SHORT: return sizeof(GLushort);
daniel@transgaming.com83921382011-01-08 05:46:00 +0000229 case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
230 default: UNREACHABLE(); return sizeof(GLushort);
daniel@transgaming.com41d8dd82010-05-12 03:45:03 +0000231 }
232}
233
daniel@transgaming.comf6549452012-01-27 15:39:08 +0000234StaticIndexBuffer *IndexDataManager::getCountingIndices(GLsizei count)
235{
236 if (count <= 65536) // 16-bit indices
237 {
238 const unsigned int spaceNeeded = count * sizeof(unsigned short);
239
240 if (!mCountingBuffer || mCountingBuffer->size() < spaceNeeded)
241 {
242 delete mCountingBuffer;
243 mCountingBuffer = new StaticIndexBuffer(mDevice);
244 mCountingBuffer->reserveSpace(spaceNeeded, GL_UNSIGNED_SHORT);
245
246 UINT offset;
247 unsigned short *data = static_cast<unsigned short*>(mCountingBuffer->map(spaceNeeded, &offset));
248
249 if (data)
250 {
251 for(int i = 0; i < count; i++)
252 {
253 data[i] = i;
254 }
255
256 mCountingBuffer->unmap();
257 }
258 }
259 }
260 else if (mStreamingBufferInt) // 32-bit indices supported
261 {
262 const unsigned int spaceNeeded = count * sizeof(unsigned int);
263
264 if (!mCountingBuffer || mCountingBuffer->size() < spaceNeeded)
265 {
266 delete mCountingBuffer;
267 mCountingBuffer = new StaticIndexBuffer(mDevice);
268 mCountingBuffer->reserveSpace(spaceNeeded, GL_UNSIGNED_INT);
269
270 UINT offset;
271 unsigned int *data = static_cast<unsigned int*>(mCountingBuffer->map(spaceNeeded, &offset));
272
273 if (data)
274 {
275 for(int i = 0; i < count; i++)
276 {
277 data[i] = i;
278 }
279
280 mCountingBuffer->unmap();
281 }
282 }
283 }
284 else return NULL;
285
286 return mCountingBuffer;
287}
288
daniel@transgaming.com83921382011-01-08 05:46:00 +0000289IndexBuffer::IndexBuffer(IDirect3DDevice9 *device, UINT size, D3DFORMAT format) : mDevice(device), mBufferSize(size), mIndexBuffer(NULL)
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +0000290{
daniel@transgaming.com83921382011-01-08 05:46:00 +0000291 if (size > 0)
292 {
daniel@transgaming.comee04e452011-01-08 05:46:27 +0000293 D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
daniel@transgaming.com37b141e2011-01-08 05:46:13 +0000294 HRESULT result = device->CreateIndexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, format, pool, &mIndexBuffer, NULL);
jbauman@chromium.orgd8f3faa2011-09-02 01:10:47 +0000295 mSerial = issueSerial();
daniel@transgaming.com83921382011-01-08 05:46:00 +0000296
297 if (FAILED(result))
298 {
299 ERR("Out of memory allocating an index buffer of size %lu.", size);
300 }
301 }
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +0000302}
303
daniel@transgaming.com83921382011-01-08 05:46:00 +0000304IndexBuffer::~IndexBuffer()
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +0000305{
daniel@transgaming.com83921382011-01-08 05:46:00 +0000306 if (mIndexBuffer)
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +0000307 {
daniel@transgaming.com83921382011-01-08 05:46:00 +0000308 mIndexBuffer->Release();
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +0000309 }
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000310}
311
daniel@transgaming.com83921382011-01-08 05:46:00 +0000312IDirect3DIndexBuffer9 *IndexBuffer::getBuffer() const
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000313{
daniel@transgaming.com83921382011-01-08 05:46:00 +0000314 return mIndexBuffer;
315}
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000316
jbauman@chromium.orgd8f3faa2011-09-02 01:10:47 +0000317unsigned int IndexBuffer::getSerial() const
318{
319 return mSerial;
320}
321
322unsigned int IndexBuffer::issueSerial()
323{
324 return mCurrentSerial++;
325}
326
daniel@transgaming.com83921382011-01-08 05:46:00 +0000327void IndexBuffer::unmap()
328{
329 if (mIndexBuffer)
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000330 {
daniel@transgaming.com83921382011-01-08 05:46:00 +0000331 mIndexBuffer->Unlock();
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000332 }
daniel@transgaming.com83921382011-01-08 05:46:00 +0000333}
334
335StreamingIndexBuffer::StreamingIndexBuffer(IDirect3DDevice9 *device, UINT initialSize, D3DFORMAT format) : IndexBuffer(device, initialSize, format)
336{
337 mWritePosition = 0;
338}
339
340StreamingIndexBuffer::~StreamingIndexBuffer()
341{
342}
343
344void *StreamingIndexBuffer::map(UINT requiredSpace, UINT *offset)
345{
346 void *mapPtr = NULL;
347
348 if (mIndexBuffer)
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000349 {
daniel@transgaming.com83921382011-01-08 05:46:00 +0000350 HRESULT result = mIndexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, D3DLOCK_NOOVERWRITE);
351
352 if (FAILED(result))
apatrick@chromium.orgf99fbb72010-11-16 01:57:05 +0000353 {
daniel@transgaming.com83921382011-01-08 05:46:00 +0000354 ERR(" Lock failed with error 0x%08x", result);
355 return NULL;
apatrick@chromium.orgf99fbb72010-11-16 01:57:05 +0000356 }
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000357
daniel@transgaming.com83921382011-01-08 05:46:00 +0000358 *offset = mWritePosition;
359 mWritePosition += requiredSpace;
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000360 }
361
daniel@transgaming.com83921382011-01-08 05:46:00 +0000362 return mapPtr;
363}
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000364
daniel@transgaming.com83921382011-01-08 05:46:00 +0000365void StreamingIndexBuffer::reserveSpace(UINT requiredSpace, GLenum type)
366{
367 if (requiredSpace > mBufferSize)
368 {
369 if (mIndexBuffer)
370 {
371 mIndexBuffer->Release();
372 mIndexBuffer = NULL;
373 }
374
375 mBufferSize = std::max(requiredSpace, 2 * mBufferSize);
376
daniel@transgaming.comee04e452011-01-08 05:46:27 +0000377 D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
daniel@transgaming.com37b141e2011-01-08 05:46:13 +0000378 HRESULT result = mDevice->CreateIndexBuffer(mBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, type == GL_UNSIGNED_INT ? D3DFMT_INDEX32 : D3DFMT_INDEX16, pool, &mIndexBuffer, NULL);
jbauman@chromium.orgd8f3faa2011-09-02 01:10:47 +0000379 mSerial = issueSerial();
daniel@transgaming.com83921382011-01-08 05:46:00 +0000380
381 if (FAILED(result))
382 {
383 ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
384 }
385
386 mWritePosition = 0;
387 }
388 else if (mWritePosition + requiredSpace > mBufferSize) // Recycle
389 {
390 void *dummy;
391 mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
392 mIndexBuffer->Unlock();
393
394 mWritePosition = 0;
395 }
396}
397
398StaticIndexBuffer::StaticIndexBuffer(IDirect3DDevice9 *device) : IndexBuffer(device, 0, D3DFMT_UNKNOWN)
399{
400 mCacheType = GL_NONE;
401}
402
403StaticIndexBuffer::~StaticIndexBuffer()
404{
405}
406
407void *StaticIndexBuffer::map(UINT requiredSpace, UINT *offset)
408{
409 void *mapPtr = NULL;
410
411 if (mIndexBuffer)
412 {
413 HRESULT result = mIndexBuffer->Lock(0, requiredSpace, &mapPtr, 0);
414
415 if (FAILED(result))
416 {
417 ERR(" Lock failed with error 0x%08x", result);
418 return NULL;
419 }
420
421 *offset = 0;
422 }
423
424 return mapPtr;
425}
426
427void StaticIndexBuffer::reserveSpace(UINT requiredSpace, GLenum type)
428{
429 if (!mIndexBuffer && mBufferSize == 0)
430 {
daniel@transgaming.comee04e452011-01-08 05:46:27 +0000431 D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_WRITEONLY);
daniel@transgaming.com37b141e2011-01-08 05:46:13 +0000432 HRESULT result = mDevice->CreateIndexBuffer(requiredSpace, D3DUSAGE_WRITEONLY, type == GL_UNSIGNED_INT ? D3DFMT_INDEX32 : D3DFMT_INDEX16, pool, &mIndexBuffer, NULL);
jbauman@chromium.orgd8f3faa2011-09-02 01:10:47 +0000433 mSerial = issueSerial();
daniel@transgaming.com83921382011-01-08 05:46:00 +0000434
435 if (FAILED(result))
436 {
437 ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
438 }
439
440 mBufferSize = requiredSpace;
441 mCacheType = type;
442 }
443 else if (mIndexBuffer && mBufferSize >= requiredSpace && mCacheType == type)
444 {
445 // Already allocated
446 }
447 else UNREACHABLE(); // Static index buffers can't be resized
448}
449
450bool StaticIndexBuffer::lookupType(GLenum type)
451{
452 return mCacheType == type;
453}
454
455UINT StaticIndexBuffer::lookupRange(intptr_t offset, GLsizei count, UINT *minIndex, UINT *maxIndex)
456{
jbauman@chromium.org43cbe742011-09-01 22:09:40 +0000457 IndexRange range = {offset, count};
daniel@transgaming.com83921382011-01-08 05:46:00 +0000458
jbauman@chromium.org43cbe742011-09-01 22:09:40 +0000459 std::map<IndexRange, IndexResult>::iterator res = mCache.find(range);
460
461 if (res == mCache.end())
462 {
463 return -1;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000464 }
465
jbauman@chromium.org43cbe742011-09-01 22:09:40 +0000466 *minIndex = res->second.minIndex;
467 *maxIndex = res->second.maxIndex;
468 return res->second.streamOffset;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000469}
470
471void StaticIndexBuffer::addRange(intptr_t offset, GLsizei count, UINT minIndex, UINT maxIndex, UINT streamOffset)
472{
jbauman@chromium.org43cbe742011-09-01 22:09:40 +0000473 IndexRange indexRange = {offset, count};
474 IndexResult indexResult = {minIndex, maxIndex, streamOffset};
475 mCache[indexRange] = indexResult;
daniel@transgaming.com81655a72010-05-20 19:18:17 +0000476}
477
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +0000478}