blob: 1dce1270d8e74d86ddc4f4141b86124d9974a9dc [file] [log] [blame]
daniel@transgaming.com955377e2012-12-20 21:09:15 +00001//
2// Copyright (c) 2002-2012 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// IndexBuffer.cpp: Defines the abstract IndexBuffer class and IndexBufferInterface
8// class with derivations, classes that perform graphics API agnostic index buffer operations.
9
Brandon Jonesc7a41042014-06-23 12:03:25 -070010#include "libGLESv2/renderer/d3d/IndexBuffer.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000011#include "libGLESv2/renderer/Renderer.h"
daniel@transgaming.com955377e2012-12-20 21:09:15 +000012
daniel@transgaming.com955377e2012-12-20 21:09:15 +000013namespace rx
14{
15
daniel@transgaming.com2befccd2012-12-20 21:09:31 +000016unsigned int IndexBuffer::mNextSerial = 1;
17
18IndexBuffer::IndexBuffer()
19{
20 updateSerial();
21}
22
23IndexBuffer::~IndexBuffer()
24{
25}
26
27unsigned int IndexBuffer::getSerial() const
28{
29 return mSerial;
30}
31
32void IndexBuffer::updateSerial()
33{
34 mSerial = mNextSerial++;
35}
36
37
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000038IndexBufferInterface::IndexBufferInterface(Renderer *renderer, bool dynamic) : mRenderer(renderer)
daniel@transgaming.com955377e2012-12-20 21:09:15 +000039{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000040 mIndexBuffer = renderer->createIndexBuffer();
daniel@transgaming.com955377e2012-12-20 21:09:15 +000041
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000042 mDynamic = dynamic;
43 mWritePosition = 0;
daniel@transgaming.com955377e2012-12-20 21:09:15 +000044}
45
daniel@transgaming.com50cc7252012-12-20 21:09:23 +000046IndexBufferInterface::~IndexBufferInterface()
daniel@transgaming.com955377e2012-12-20 21:09:15 +000047{
48 if (mIndexBuffer)
49 {
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000050 delete mIndexBuffer;
daniel@transgaming.com955377e2012-12-20 21:09:15 +000051 }
52}
53
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000054GLenum IndexBufferInterface::getIndexType() const
daniel@transgaming.com955377e2012-12-20 21:09:15 +000055{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000056 return mIndexBuffer->getIndexType();
57}
58
59unsigned int IndexBufferInterface::getBufferSize() const
60{
61 return mIndexBuffer->getBufferSize();
daniel@transgaming.com955377e2012-12-20 21:09:15 +000062}
63
daniel@transgaming.com50cc7252012-12-20 21:09:23 +000064unsigned int IndexBufferInterface::getSerial() const
daniel@transgaming.com955377e2012-12-20 21:09:15 +000065{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000066 return mIndexBuffer->getSerial();
daniel@transgaming.com955377e2012-12-20 21:09:15 +000067}
68
Geoff Langc9e69b12014-09-08 16:06:25 -040069gl::Error IndexBufferInterface::mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset)
daniel@transgaming.com955377e2012-12-20 21:09:15 +000070{
Geoff Langa36ead42013-08-02 11:54:08 -040071 // Protect against integer overflow
72 if (mWritePosition + size < mWritePosition)
daniel@transgaming.com955377e2012-12-20 21:09:15 +000073 {
Geoff Langc9e69b12014-09-08 16:06:25 -040074 return gl::Error(GL_OUT_OF_MEMORY, "Mapping of internal index buffer would cause an integer overflow.");
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000075 }
76
Geoff Langc9e69b12014-09-08 16:06:25 -040077 gl::Error error = mIndexBuffer->mapBuffer(mWritePosition, size, outMappedMemory);
78 if (error.isError())
Geoff Langa36ead42013-08-02 11:54:08 -040079 {
80 if (outMappedMemory)
81 {
82 *outMappedMemory = NULL;
83 }
Geoff Langc9e69b12014-09-08 16:06:25 -040084 return error;
Geoff Langa36ead42013-08-02 11:54:08 -040085 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000086
Geoff Langa36ead42013-08-02 11:54:08 -040087 if (streamOffset)
88 {
89 *streamOffset = mWritePosition;
90 }
91
92 mWritePosition += size;
Geoff Langc9e69b12014-09-08 16:06:25 -040093 return gl::Error(GL_NO_ERROR);
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000094}
95
Geoff Langc9e69b12014-09-08 16:06:25 -040096gl::Error IndexBufferInterface::unmapBuffer()
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000097{
98 return mIndexBuffer->unmapBuffer();
99}
100
101IndexBuffer * IndexBufferInterface::getIndexBuffer() const
102{
103 return mIndexBuffer;
104}
105
106unsigned int IndexBufferInterface::getWritePosition() const
107{
108 return mWritePosition;
109}
110
111void IndexBufferInterface::setWritePosition(unsigned int writePosition)
112{
113 mWritePosition = writePosition;
114}
115
Geoff Langc9e69b12014-09-08 16:06:25 -0400116gl::Error IndexBufferInterface::discard()
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000117{
118 return mIndexBuffer->discard();
119}
120
Geoff Langc9e69b12014-09-08 16:06:25 -0400121gl::Error IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum indexType)
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000122{
123 if (mIndexBuffer->getBufferSize() == 0)
124 {
125 return mIndexBuffer->initialize(bufferSize, indexType, mDynamic);
126 }
127 else
128 {
129 return mIndexBuffer->setSize(bufferSize, indexType);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000130 }
131}
132
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000133StreamingIndexBufferInterface::StreamingIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, true)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000134{
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000135}
136
daniel@transgaming.com50cc7252012-12-20 21:09:23 +0000137StreamingIndexBufferInterface::~StreamingIndexBufferInterface()
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000138{
139}
140
Geoff Langc9e69b12014-09-08 16:06:25 -0400141gl::Error StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000142{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000143 unsigned int curBufferSize = getBufferSize();
Geoff Langd81cf642013-07-09 16:02:30 -0400144 unsigned int writePos = getWritePosition();
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000145 if (size > curBufferSize)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000146 {
Geoff Langc9e69b12014-09-08 16:06:25 -0400147 gl::Error error = setBufferSize(std::max(size, 2 * curBufferSize), indexType);
148 if (error.isError())
149 {
150 return error;
151 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000152 setWritePosition(0);
153 }
Geoff Langd81cf642013-07-09 16:02:30 -0400154 else if (writePos + size > curBufferSize || writePos + size < writePos)
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000155 {
Geoff Langc9e69b12014-09-08 16:06:25 -0400156 gl::Error error = discard();
157 if (error.isError())
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000158 {
Geoff Langc9e69b12014-09-08 16:06:25 -0400159 return error;
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000160 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000161 setWritePosition(0);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000162 }
163
Geoff Langc9e69b12014-09-08 16:06:25 -0400164 return gl::Error(GL_NO_ERROR);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000165}
166
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000167
168StaticIndexBufferInterface::StaticIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, false)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000169{
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000170}
171
daniel@transgaming.com50cc7252012-12-20 21:09:23 +0000172StaticIndexBufferInterface::~StaticIndexBufferInterface()
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000173{
174}
175
Geoff Langc9e69b12014-09-08 16:06:25 -0400176gl::Error StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000177{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000178 unsigned int curSize = getBufferSize();
179 if (curSize == 0)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000180 {
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000181 return setBufferSize(size, indexType);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000182 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000183 else if (curSize >= size && indexType == getIndexType())
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000184 {
Geoff Langc9e69b12014-09-08 16:06:25 -0400185 return gl::Error(GL_NO_ERROR);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000186 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000187 else
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000188 {
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000189 UNREACHABLE();
Geoff Langc9e69b12014-09-08 16:06:25 -0400190 return gl::Error(GL_INVALID_OPERATION, "Internal static index buffers can't be resized");
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000191 }
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000192}
193
Geoff Langf23eb282013-07-22 10:52:19 -0400194IndexRangeCache *StaticIndexBufferInterface::getIndexRangeCache()
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000195{
Geoff Langf23eb282013-07-22 10:52:19 -0400196 return &mIndexRangeCache;
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000197}
198
199}