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
IndexBuffer()19 IndexBuffer::IndexBuffer()
20 {
21 updateSerial();
22 }
23
~IndexBuffer()24 IndexBuffer::~IndexBuffer()
25 {
26 }
27
getSerial() const28 unsigned int IndexBuffer::getSerial() const
29 {
30 return mSerial;
31 }
32
updateSerial()33 void IndexBuffer::updateSerial()
34 {
35 mSerial = mNextSerial++;
36 }
37
38
IndexBufferInterface(Renderer * renderer,bool dynamic)39 IndexBufferInterface::IndexBufferInterface(Renderer *renderer, bool dynamic) : mRenderer(renderer)
40 {
41 mIndexBuffer = renderer->createIndexBuffer();
42
43 mDynamic = dynamic;
44 mWritePosition = 0;
45 }
46
~IndexBufferInterface()47 IndexBufferInterface::~IndexBufferInterface()
48 {
49 if (mIndexBuffer)
50 {
51 delete mIndexBuffer;
52 }
53 }
54
getIndexType() const55 GLenum IndexBufferInterface::getIndexType() const
56 {
57 return mIndexBuffer->getIndexType();
58 }
59
getBufferSize() const60 unsigned int IndexBufferInterface::getBufferSize() const
61 {
62 return mIndexBuffer->getBufferSize();
63 }
64
getSerial() const65 unsigned int IndexBufferInterface::getSerial() const
66 {
67 return mIndexBuffer->getSerial();
68 }
69
mapBuffer(unsigned int size,void ** outMappedMemory,unsigned int * streamOffset)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
unmapBuffer()96 bool IndexBufferInterface::unmapBuffer()
97 {
98 return mIndexBuffer->unmapBuffer();
99 }
100
getIndexBuffer() const101 IndexBuffer * IndexBufferInterface::getIndexBuffer() const
102 {
103 return mIndexBuffer;
104 }
105
getWritePosition() const106 unsigned int IndexBufferInterface::getWritePosition() const
107 {
108 return mWritePosition;
109 }
110
setWritePosition(unsigned int writePosition)111 void IndexBufferInterface::setWritePosition(unsigned int writePosition)
112 {
113 mWritePosition = writePosition;
114 }
115
discard()116 bool IndexBufferInterface::discard()
117 {
118 return mIndexBuffer->discard();
119 }
120
setBufferSize(unsigned int bufferSize,GLenum indexType)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
StreamingIndexBufferInterface(Renderer * renderer)133 StreamingIndexBufferInterface::StreamingIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, true)
134 {
135 }
136
~StreamingIndexBufferInterface()137 StreamingIndexBufferInterface::~StreamingIndexBufferInterface()
138 {
139 }
140
reserveBufferSpace(unsigned int size,GLenum indexType)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
StaticIndexBufferInterface(Renderer * renderer)164 StaticIndexBufferInterface::StaticIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, false)
165 {
166 }
167
~StaticIndexBufferInterface()168 StaticIndexBufferInterface::~StaticIndexBufferInterface()
169 {
170 }
171
reserveBufferSpace(unsigned int size,GLenum indexType)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
getIndexRangeCache()191 IndexRangeCache *StaticIndexBufferInterface::getIndexRangeCache()
192 {
193 return &mIndexRangeCache;
194 }
195
196 }
197
198