• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // VertexBuffer.cpp: Defines the abstract VertexBuffer class and VertexBufferInterface
9 // class with derivations, classes that perform graphics API agnostic vertex buffer operations.
10 
11 #include "libGLESv2/renderer/VertexBuffer.h"
12 #include "libGLESv2/renderer/Renderer.h"
13 #include "libGLESv2/Context.h"
14 
15 namespace rx
16 {
17 
18 unsigned int VertexBuffer::mNextSerial = 1;
19 
VertexBuffer()20 VertexBuffer::VertexBuffer()
21 {
22     updateSerial();
23 }
24 
~VertexBuffer()25 VertexBuffer::~VertexBuffer()
26 {
27 }
28 
updateSerial()29 void VertexBuffer::updateSerial()
30 {
31     mSerial = mNextSerial++;
32 }
33 
getSerial() const34 unsigned int VertexBuffer::getSerial() const
35 {
36     return mSerial;
37 }
38 
VertexBufferInterface(rx::Renderer * renderer,bool dynamic)39 VertexBufferInterface::VertexBufferInterface(rx::Renderer *renderer, bool dynamic) : mRenderer(renderer)
40 {
41     mDynamic = dynamic;
42     mWritePosition = 0;
43     mReservedSpace = 0;
44 
45     mVertexBuffer = renderer->createVertexBuffer();
46 }
47 
~VertexBufferInterface()48 VertexBufferInterface::~VertexBufferInterface()
49 {
50     delete mVertexBuffer;
51 }
52 
getSerial() const53 unsigned int VertexBufferInterface::getSerial() const
54 {
55     return mVertexBuffer->getSerial();
56 }
57 
getBufferSize() const58 unsigned int VertexBufferInterface::getBufferSize() const
59 {
60     return mVertexBuffer->getBufferSize();
61 }
62 
setBufferSize(unsigned int size)63 bool VertexBufferInterface::setBufferSize(unsigned int size)
64 {
65     if (mVertexBuffer->getBufferSize() == 0)
66     {
67         return mVertexBuffer->initialize(size, mDynamic);
68     }
69     else
70     {
71         return mVertexBuffer->setBufferSize(size);
72     }
73 }
74 
getWritePosition() const75 unsigned int VertexBufferInterface::getWritePosition() const
76 {
77     return mWritePosition;
78 }
79 
setWritePosition(unsigned int writePosition)80 void VertexBufferInterface::setWritePosition(unsigned int writePosition)
81 {
82     mWritePosition = writePosition;
83 }
84 
discard()85 bool VertexBufferInterface::discard()
86 {
87     return mVertexBuffer->discard();
88 }
89 
storeVertexAttributes(const gl::VertexAttribute & attrib,GLint start,GLsizei count,GLsizei instances,unsigned int * outStreamOffset)90 bool VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib,  GLint start, GLsizei count, GLsizei instances,
91                                                   unsigned int *outStreamOffset)
92 {
93     unsigned int spaceRequired;
94     if (!mVertexBuffer->getSpaceRequired(attrib, count, instances, &spaceRequired))
95     {
96         return false;
97     }
98 
99     if (mWritePosition + spaceRequired < mWritePosition)
100     {
101         return false;
102     }
103 
104     if (!reserveSpace(mReservedSpace))
105     {
106         return false;
107     }
108     mReservedSpace = 0;
109 
110     if (!mVertexBuffer->storeVertexAttributes(attrib, start, count, instances, mWritePosition))
111     {
112         return false;
113     }
114 
115     if (outStreamOffset)
116     {
117         *outStreamOffset = mWritePosition;
118     }
119 
120     mWritePosition += spaceRequired;
121 
122     return true;
123 }
124 
storeRawData(const void * data,unsigned int size,unsigned int * outStreamOffset)125 bool VertexBufferInterface::storeRawData(const void* data, unsigned int size, unsigned int *outStreamOffset)
126 {
127     if (mWritePosition + size < mWritePosition)
128     {
129         return false;
130     }
131 
132     if (!reserveSpace(mReservedSpace))
133     {
134         return false;
135     }
136     mReservedSpace = 0;
137 
138     if (!mVertexBuffer->storeRawData(data, size, mWritePosition))
139     {
140         return false;
141     }
142 
143     if (outStreamOffset)
144     {
145         *outStreamOffset = mWritePosition;
146     }
147 
148     mWritePosition += size;
149 
150     return true;
151 }
152 
reserveVertexSpace(const gl::VertexAttribute & attribute,GLsizei count,GLsizei instances)153 bool VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances)
154 {
155     unsigned int requiredSpace;
156     if (!mVertexBuffer->getSpaceRequired(attribute, count, instances, &requiredSpace))
157     {
158         return false;
159     }
160 
161     // Protect against integer overflow
162     if (mReservedSpace + requiredSpace < mReservedSpace)
163     {
164          return false;
165     }
166 
167     mReservedSpace += requiredSpace;
168     return true;
169 }
170 
reserveRawDataSpace(unsigned int size)171 bool VertexBufferInterface::reserveRawDataSpace(unsigned int size)
172 {
173     // Protect against integer overflow
174     if (mReservedSpace + size < mReservedSpace)
175     {
176          return false;
177     }
178 
179     mReservedSpace += size;
180     return true;
181 }
182 
getVertexBuffer() const183 VertexBuffer* VertexBufferInterface::getVertexBuffer() const
184 {
185     return mVertexBuffer;
186 }
187 
188 
StreamingVertexBufferInterface(rx::Renderer * renderer,std::size_t initialSize)189 StreamingVertexBufferInterface::StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true)
190 {
191     setBufferSize(initialSize);
192 }
193 
~StreamingVertexBufferInterface()194 StreamingVertexBufferInterface::~StreamingVertexBufferInterface()
195 {
196 }
197 
reserveSpace(unsigned int size)198 bool StreamingVertexBufferInterface::reserveSpace(unsigned int size)
199 {
200     bool result = true;
201     unsigned int curBufferSize = getBufferSize();
202     if (size > curBufferSize)
203     {
204         result = setBufferSize(std::max(size, 3 * curBufferSize / 2));
205         setWritePosition(0);
206     }
207     else if (getWritePosition() + size > curBufferSize)
208     {
209         if (!discard())
210         {
211             return false;
212         }
213         setWritePosition(0);
214     }
215 
216     return result;
217 }
218 
StaticVertexBufferInterface(rx::Renderer * renderer)219 StaticVertexBufferInterface::StaticVertexBufferInterface(rx::Renderer *renderer) : VertexBufferInterface(renderer, false)
220 {
221 }
222 
~StaticVertexBufferInterface()223 StaticVertexBufferInterface::~StaticVertexBufferInterface()
224 {
225 }
226 
lookupAttribute(const gl::VertexAttribute & attribute,unsigned int * outStreamOffset)227 bool StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attribute, unsigned int *outStreamOffset)
228 {
229     for (unsigned int element = 0; element < mCache.size(); element++)
230     {
231         if (mCache[element].type == attribute.mType &&
232             mCache[element].size == attribute.mSize &&
233             mCache[element].stride == attribute.stride() &&
234             mCache[element].normalized == attribute.mNormalized)
235         {
236             if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride())
237             {
238                 if (outStreamOffset)
239                 {
240                     *outStreamOffset = mCache[element].streamOffset;
241                 }
242                 return true;
243             }
244         }
245     }
246 
247     return false;
248 }
249 
reserveSpace(unsigned int size)250 bool StaticVertexBufferInterface::reserveSpace(unsigned int size)
251 {
252     unsigned int curSize = getBufferSize();
253     if (curSize == 0)
254     {
255         setBufferSize(size);
256         return true;
257     }
258     else if (curSize >= size)
259     {
260         return true;
261     }
262     else
263     {
264         UNREACHABLE();   // Static vertex buffers can't be resized
265         return false;
266     }
267 }
268 
storeVertexAttributes(const gl::VertexAttribute & attrib,GLint start,GLsizei count,GLsizei instances,unsigned int * outStreamOffset)269 bool StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances,
270                                                         unsigned int *outStreamOffset)
271 {
272     unsigned int streamOffset;
273     if (VertexBufferInterface::storeVertexAttributes(attrib, start, count, instances, &streamOffset))
274     {
275         int attributeOffset = attrib.mOffset % attrib.stride();
276         VertexElement element = { attrib.mType, attrib.mSize, attrib.stride(), attrib.mNormalized, attributeOffset, streamOffset };
277         mCache.push_back(element);
278 
279         if (outStreamOffset)
280         {
281             *outStreamOffset = streamOffset;
282         }
283 
284         return true;
285     }
286     else
287     {
288         return false;
289     }
290 }
291 
292 }
293