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