Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / libGLESv2 / renderer / VertexBuffer.cpp
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
20 VertexBuffer::VertexBuffer()
21 {
22     updateSerial();
23 }
24
25 VertexBuffer::~VertexBuffer()
26 {
27 }
28
29 void VertexBuffer::updateSerial()
30 {
31     mSerial = mNextSerial++;
32 }
33
34 unsigned int VertexBuffer::getSerial() const
35 {
36     return mSerial;
37 }
38
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
48 VertexBufferInterface::~VertexBufferInterface()
49 {
50     delete mVertexBuffer;
51 }
52
53 unsigned int VertexBufferInterface::getSerial() const
54 {
55     return mVertexBuffer->getSerial();
56 }
57
58 unsigned int VertexBufferInterface::getBufferSize() const
59 {
60     return mVertexBuffer->getBufferSize();
61 }
62
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
75 unsigned int VertexBufferInterface::getWritePosition() const
76 {
77     return mWritePosition;
78 }
79
80 void VertexBufferInterface::setWritePosition(unsigned int writePosition)
81 {
82     mWritePosition = writePosition;
83 }
84
85 bool VertexBufferInterface::discard()
86 {
87     return mVertexBuffer->discard();
88 }
89
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
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
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
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
183 VertexBuffer* VertexBufferInterface::getVertexBuffer() const
184 {
185     return mVertexBuffer;
186 }
187
188
189 StreamingVertexBufferInterface::StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true)
190 {
191     setBufferSize(initialSize);
192 }
193
194 StreamingVertexBufferInterface::~StreamingVertexBufferInterface()
195 {
196 }
197
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
219 StaticVertexBufferInterface::StaticVertexBufferInterface(rx::Renderer *renderer) : VertexBufferInterface(renderer, false)
220 {
221 }
222
223 StaticVertexBufferInterface::~StaticVertexBufferInterface()
224 {
225 }
226
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
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
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 }