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