blob: b0e864c21011da75396c6b276e5a30e701a01355 [file] [log] [blame]
daniel@transgaming.comf8b58a02010-03-26 04:08:45 +00001//
2// Copyright (c) 2002-2010 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// geometry/IndexDataManager.cpp: Defines the IndexDataManager, a class that
8// runs the Buffer translation process for index buffers.
9
10#include "geometry/IndexDataManager.h"
11
12#include "common/debug.h"
13#include "Buffer.h"
14#include "geometry/backend.h"
15
16namespace
17{
18 enum { INITIAL_INDEX_BUFFER_SIZE = sizeof(gl::Index) * 8192 };
19}
20
21namespace gl
22{
23
24IndexDataManager::IndexDataManager(Context *context, BufferBackEnd *backend)
25 : mContext(context), mBackend(backend)
26{
27 mStreamBuffer = mBackend->createIndexBuffer(INITIAL_INDEX_BUFFER_SIZE);
28}
29
30IndexDataManager::~IndexDataManager()
31{
32 delete mStreamBuffer;
33}
34
35namespace
36{
37
38template <class InputIndexType>
39void copyIndices(const InputIndexType *in, GLsizei count, Index *out, GLuint *minIndex, GLuint *maxIndex)
40{
41 GLuint minIndexSoFar = *in;
42 GLuint maxIndexSoFar = *in;
43
44 for (GLsizei i = 0; i < count; i++)
45 {
46 if (minIndexSoFar > *in) minIndexSoFar = *in;
47 if (maxIndexSoFar < *in) maxIndexSoFar = *in;
48
49 *out++ = *in++;
50 }
51
52 *minIndex = minIndexSoFar;
53 *maxIndex = maxIndexSoFar;
54}
55
56}
57
58TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices)
59{
60 ASSERT(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_BYTE);
61 ASSERT(count > 0);
62
63 TranslatedIndexData translated;
64
65 translated.count = count;
66
67 std::size_t requiredSpace = spaceRequired(mode, type, count);
68
69 if (requiredSpace > mStreamBuffer->size())
70 {
71 std::size_t newSize = std::max(requiredSpace, 2 * mStreamBuffer->size());
72
73 TranslatedIndexBuffer *newStreamBuffer = mBackend->createIndexBuffer(newSize);
74
75 delete mStreamBuffer;
76 mStreamBuffer = newStreamBuffer;
77 }
78
79 mStreamBuffer->reserveSpace(requiredSpace);
80
81 size_t offset;
82 void *output = mStreamBuffer->map(requiredSpace, &offset);
83
84 translated.buffer = mStreamBuffer;
85 translated.offset = offset;
86
87 translated.indices = static_cast<const Index*>(output);
88
89 if (arrayElementBuffer != NULL)
90 {
91 indices = static_cast<const GLubyte*>(arrayElementBuffer->data()) + reinterpret_cast<GLsizei>(indices);
92 }
93
94 Index *out = static_cast<Index*>(output);
95
96 if (type == GL_UNSIGNED_SHORT)
97 {
98 const GLushort *in = static_cast<const GLushort*>(indices);
99
100 copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex);
101 }
102 else
103 {
104 const GLubyte *in = static_cast<const GLubyte*>(indices);
105
106 copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex);
107 }
108
109 mStreamBuffer->unmap();
110
111 return translated;
112}
113
114std::size_t IndexDataManager::spaceRequired(GLenum mode, GLenum type, GLsizei count)
115{
116 return count * sizeof(Index);
117}
118
119}