blob: 5c8ddc858ec77ea7d7ff5a5aac0460b2eb223402 [file] [log] [blame]
daniel@transgaming.com29787c32012-12-20 20:55:48 +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
daniel@transgaming.comdcfb1f72012-12-20 20:57:03 +00007// VertexBuffer.cpp: Defines the abstract VertexBuffer class and VertexBufferInterface
8// class with derivations, classes that perform graphics API agnostic vertex buffer operations.
daniel@transgaming.com29787c32012-12-20 20:55:48 +00009
10#include "libGLESv2/renderer/VertexBuffer.h"
shannon.woods@transgaming.comd2811d62013-02-28 23:11:19 +000011#include "libGLESv2/renderer/Renderer.h"
12#include "libGLESv2/Context.h"
daniel@transgaming.com29787c32012-12-20 20:55:48 +000013
daniel@transgaming.com29787c32012-12-20 20:55:48 +000014namespace rx
15{
16
daniel@transgaming.comdcfb1f72012-12-20 20:57:03 +000017unsigned int VertexBuffer::mNextSerial = 1;
18
19VertexBuffer::VertexBuffer()
20{
21 updateSerial();
22}
23
24VertexBuffer::~VertexBuffer()
25{
26}
27
28void VertexBuffer::updateSerial()
29{
30 mSerial = mNextSerial++;
31}
32
33unsigned int VertexBuffer::getSerial() const
34{
35 return mSerial;
36}
37
daniel@transgaming.com4150d362012-12-20 21:07:43 +000038VertexBufferInterface::VertexBufferInterface(rx::Renderer *renderer, bool dynamic) : mRenderer(renderer)
daniel@transgaming.com29787c32012-12-20 20:55:48 +000039{
daniel@transgaming.com4150d362012-12-20 21:07:43 +000040 mDynamic = dynamic;
daniel@transgaming.coma41d07f2012-12-20 20:55:57 +000041 mWritePosition = 0;
daniel@transgaming.com4150d362012-12-20 21:07:43 +000042 mReservedSpace = 0;
43
44 mVertexBuffer = renderer->createVertexBuffer();
daniel@transgaming.com29787c32012-12-20 20:55:48 +000045}
46
daniel@transgaming.come4e45062012-12-20 20:56:53 +000047VertexBufferInterface::~VertexBufferInterface()
daniel@transgaming.com29787c32012-12-20 20:55:48 +000048{
daniel@transgaming.com4150d362012-12-20 21:07:43 +000049 delete mVertexBuffer;
daniel@transgaming.com29787c32012-12-20 20:55:48 +000050}
51
daniel@transgaming.come4e45062012-12-20 20:56:53 +000052unsigned int VertexBufferInterface::getSerial() const
daniel@transgaming.com29787c32012-12-20 20:55:48 +000053{
daniel@transgaming.com4150d362012-12-20 21:07:43 +000054 return mVertexBuffer->getSerial();
daniel@transgaming.com29787c32012-12-20 20:55:48 +000055}
56
daniel@transgaming.com4150d362012-12-20 21:07:43 +000057unsigned int VertexBufferInterface::getBufferSize() const
daniel@transgaming.com29787c32012-12-20 20:55:48 +000058{
daniel@transgaming.com4150d362012-12-20 21:07:43 +000059 return mVertexBuffer->getBufferSize();
daniel@transgaming.com29787c32012-12-20 20:55:48 +000060}
61
daniel@transgaming.com4150d362012-12-20 21:07:43 +000062bool VertexBufferInterface::setBufferSize(unsigned int size)
daniel@transgaming.com29787c32012-12-20 20:55:48 +000063{
daniel@transgaming.com4150d362012-12-20 21:07:43 +000064 if (mVertexBuffer->getBufferSize() == 0)
65 {
66 return mVertexBuffer->initialize(size, mDynamic);
67 }
68 else
69 {
70 return mVertexBuffer->setBufferSize(size);
71 }
daniel@transgaming.com29787c32012-12-20 20:55:48 +000072}
73
daniel@transgaming.com4150d362012-12-20 21:07:43 +000074unsigned int VertexBufferInterface::getWritePosition() const
daniel@transgaming.com29787c32012-12-20 20:55:48 +000075{
daniel@transgaming.com4150d362012-12-20 21:07:43 +000076 return mWritePosition;
77}
78
79void VertexBufferInterface::setWritePosition(unsigned int writePosition)
80{
81 mWritePosition = writePosition;
82}
83
84bool VertexBufferInterface::discard()
85{
86 return mVertexBuffer->discard();
87}
88
89int VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances)
90{
91 if (!reserveSpace(mReservedSpace))
92 {
93 return -1;
94 }
95 mReservedSpace = 0;
96
97 if (!mVertexBuffer->storeVertexAttributes(attrib, start, count, instances, mWritePosition))
98 {
99 return -1;
100 }
101
102 int oldWritePos = static_cast<int>(mWritePosition);
103 mWritePosition += mVertexBuffer->getSpaceRequired(attrib, count, instances);
104
105 return oldWritePos;
106}
107
108int VertexBufferInterface::storeRawData(const void* data, unsigned int size)
109{
110 if (!reserveSpace(mReservedSpace))
111 {
112 return -1;
113 }
114 mReservedSpace = 0;
115
116 if (!mVertexBuffer->storeRawData(data, size, mWritePosition))
117 {
118 return -1;
119 }
120
121 int oldWritePos = static_cast<int>(mWritePosition);
122 mWritePosition += size;
123
124 return oldWritePos;
125}
126
127void VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances)
128{
129 mReservedSpace += mVertexBuffer->getSpaceRequired(attribute, count, instances);
130}
131
132void VertexBufferInterface::reserveRawDataSpace(unsigned int size)
133{
134 mReservedSpace += size;
135}
136
137VertexBuffer* VertexBufferInterface::getVertexBuffer() const
138{
139 return mVertexBuffer;
140}
141
142
143StreamingVertexBufferInterface::StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true)
144{
145 setBufferSize(initialSize);
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000146}
147
daniel@transgaming.come4e45062012-12-20 20:56:53 +0000148StreamingVertexBufferInterface::~StreamingVertexBufferInterface()
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000149{
150}
151
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000152bool StreamingVertexBufferInterface::reserveSpace(unsigned int size)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000153{
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000154 bool result = true;
155 unsigned int curBufferSize = getBufferSize();
156 if (size > curBufferSize)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000157 {
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000158 result = setBufferSize(std::max(size, 3 * curBufferSize / 2));
159 setWritePosition(0);
160 }
161 else if (getWritePosition() + size > curBufferSize)
162 {
163 if (!discard())
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000164 {
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000165 return false;
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000166 }
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000167 setWritePosition(0);
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000168 }
169
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000170 return result;
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000171}
172
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000173StaticVertexBufferInterface::StaticVertexBufferInterface(rx::Renderer *renderer) : VertexBufferInterface(renderer, false)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000174{
175}
176
daniel@transgaming.come4e45062012-12-20 20:56:53 +0000177StaticVertexBufferInterface::~StaticVertexBufferInterface()
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000178{
179}
180
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000181int StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attribute)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000182{
183 for (unsigned int element = 0; element < mCache.size(); element++)
184 {
185 if (mCache[element].type == attribute.mType &&
186 mCache[element].size == attribute.mSize &&
187 mCache[element].stride == attribute.stride() &&
188 mCache[element].normalized == attribute.mNormalized)
189 {
190 if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride())
191 {
192 return mCache[element].streamOffset;
193 }
194 }
195 }
196
197 return -1;
198}
199
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000200bool StaticVertexBufferInterface::reserveSpace(unsigned int size)
201{
202 unsigned int curSize = getBufferSize();
203 if (curSize == 0)
204 {
205 setBufferSize(size);
206 return true;
207 }
208 else if (curSize >= size)
209 {
210 return true;
211 }
212 else
213 {
214 UNREACHABLE(); // Static vertex buffers can't be resized
215 return false;
216 }
217}
218
219int StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances)
220{
221 int attributeOffset = attrib.mOffset % attrib.stride();
222 VertexElement element = { attrib.mType, attrib.mSize, attrib.stride(), attrib.mNormalized, attributeOffset, getWritePosition() };
223 mCache.push_back(element);
224
225 return VertexBufferInterface::storeVertexAttributes(attrib, start, count, instances);
226}
227
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000228}