• 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