blob: 7ffe2da7c06b28226d24ad29446bf2b28aabcc76 [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"
11
daniel@transgaming.com29787c32012-12-20 20:55:48 +000012namespace rx
13{
14
daniel@transgaming.comdcfb1f72012-12-20 20:57:03 +000015unsigned int VertexBuffer::mNextSerial = 1;
16
17VertexBuffer::VertexBuffer()
18{
19 updateSerial();
20}
21
22VertexBuffer::~VertexBuffer()
23{
24}
25
26void VertexBuffer::updateSerial()
27{
28 mSerial = mNextSerial++;
29}
30
31unsigned int VertexBuffer::getSerial() const
32{
33 return mSerial;
34}
35
daniel@transgaming.com4150d362012-12-20 21:07:43 +000036VertexBufferInterface::VertexBufferInterface(rx::Renderer *renderer, bool dynamic) : mRenderer(renderer)
daniel@transgaming.com29787c32012-12-20 20:55:48 +000037{
daniel@transgaming.com4150d362012-12-20 21:07:43 +000038 mDynamic = dynamic;
daniel@transgaming.coma41d07f2012-12-20 20:55:57 +000039 mWritePosition = 0;
daniel@transgaming.com4150d362012-12-20 21:07:43 +000040 mReservedSpace = 0;
41
42 mVertexBuffer = renderer->createVertexBuffer();
daniel@transgaming.com29787c32012-12-20 20:55:48 +000043}
44
daniel@transgaming.come4e45062012-12-20 20:56:53 +000045VertexBufferInterface::~VertexBufferInterface()
daniel@transgaming.com29787c32012-12-20 20:55:48 +000046{
daniel@transgaming.com4150d362012-12-20 21:07:43 +000047 delete mVertexBuffer;
daniel@transgaming.com29787c32012-12-20 20:55:48 +000048}
49
daniel@transgaming.come4e45062012-12-20 20:56:53 +000050unsigned int VertexBufferInterface::getSerial() const
daniel@transgaming.com29787c32012-12-20 20:55:48 +000051{
daniel@transgaming.com4150d362012-12-20 21:07:43 +000052 return mVertexBuffer->getSerial();
daniel@transgaming.com29787c32012-12-20 20:55:48 +000053}
54
daniel@transgaming.com4150d362012-12-20 21:07:43 +000055unsigned int VertexBufferInterface::getBufferSize() const
daniel@transgaming.com29787c32012-12-20 20:55:48 +000056{
daniel@transgaming.com4150d362012-12-20 21:07:43 +000057 return mVertexBuffer->getBufferSize();
daniel@transgaming.com29787c32012-12-20 20:55:48 +000058}
59
daniel@transgaming.com4150d362012-12-20 21:07:43 +000060bool VertexBufferInterface::setBufferSize(unsigned int size)
daniel@transgaming.com29787c32012-12-20 20:55:48 +000061{
daniel@transgaming.com4150d362012-12-20 21:07:43 +000062 if (mVertexBuffer->getBufferSize() == 0)
63 {
64 return mVertexBuffer->initialize(size, mDynamic);
65 }
66 else
67 {
68 return mVertexBuffer->setBufferSize(size);
69 }
daniel@transgaming.com29787c32012-12-20 20:55:48 +000070}
71
daniel@transgaming.com4150d362012-12-20 21:07:43 +000072unsigned int VertexBufferInterface::getWritePosition() const
daniel@transgaming.com29787c32012-12-20 20:55:48 +000073{
daniel@transgaming.com4150d362012-12-20 21:07:43 +000074 return mWritePosition;
75}
76
77void VertexBufferInterface::setWritePosition(unsigned int writePosition)
78{
79 mWritePosition = writePosition;
80}
81
82bool VertexBufferInterface::discard()
83{
84 return mVertexBuffer->discard();
85}
86
87int VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances)
88{
89 if (!reserveSpace(mReservedSpace))
90 {
91 return -1;
92 }
93 mReservedSpace = 0;
94
95 if (!mVertexBuffer->storeVertexAttributes(attrib, start, count, instances, mWritePosition))
96 {
97 return -1;
98 }
99
100 int oldWritePos = static_cast<int>(mWritePosition);
101 mWritePosition += mVertexBuffer->getSpaceRequired(attrib, count, instances);
102
103 return oldWritePos;
104}
105
106int VertexBufferInterface::storeRawData(const void* data, unsigned int size)
107{
108 if (!reserveSpace(mReservedSpace))
109 {
110 return -1;
111 }
112 mReservedSpace = 0;
113
114 if (!mVertexBuffer->storeRawData(data, size, mWritePosition))
115 {
116 return -1;
117 }
118
119 int oldWritePos = static_cast<int>(mWritePosition);
120 mWritePosition += size;
121
122 return oldWritePos;
123}
124
125void VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances)
126{
127 mReservedSpace += mVertexBuffer->getSpaceRequired(attribute, count, instances);
128}
129
130void VertexBufferInterface::reserveRawDataSpace(unsigned int size)
131{
132 mReservedSpace += size;
133}
134
135VertexBuffer* VertexBufferInterface::getVertexBuffer() const
136{
137 return mVertexBuffer;
138}
139
140
141StreamingVertexBufferInterface::StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true)
142{
143 setBufferSize(initialSize);
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000144}
145
daniel@transgaming.come4e45062012-12-20 20:56:53 +0000146StreamingVertexBufferInterface::~StreamingVertexBufferInterface()
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000147{
148}
149
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000150bool StreamingVertexBufferInterface::reserveSpace(unsigned int size)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000151{
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000152 bool result = true;
153 unsigned int curBufferSize = getBufferSize();
154 if (size > curBufferSize)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000155 {
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000156 result = setBufferSize(std::max(size, 3 * curBufferSize / 2));
157 setWritePosition(0);
158 }
159 else if (getWritePosition() + size > curBufferSize)
160 {
161 if (!discard())
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000162 {
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000163 return false;
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000164 }
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000165 setWritePosition(0);
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000166 }
167
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000168 return result;
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000169}
170
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000171StaticVertexBufferInterface::StaticVertexBufferInterface(rx::Renderer *renderer) : VertexBufferInterface(renderer, false)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000172{
173}
174
daniel@transgaming.come4e45062012-12-20 20:56:53 +0000175StaticVertexBufferInterface::~StaticVertexBufferInterface()
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000176{
177}
178
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000179int StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attribute)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000180{
181 for (unsigned int element = 0; element < mCache.size(); element++)
182 {
183 if (mCache[element].type == attribute.mType &&
184 mCache[element].size == attribute.mSize &&
185 mCache[element].stride == attribute.stride() &&
186 mCache[element].normalized == attribute.mNormalized)
187 {
188 if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride())
189 {
190 return mCache[element].streamOffset;
191 }
192 }
193 }
194
195 return -1;
196}
197
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000198bool StaticVertexBufferInterface::reserveSpace(unsigned int size)
199{
200 unsigned int curSize = getBufferSize();
201 if (curSize == 0)
202 {
203 setBufferSize(size);
204 return true;
205 }
206 else if (curSize >= size)
207 {
208 return true;
209 }
210 else
211 {
212 UNREACHABLE(); // Static vertex buffers can't be resized
213 return false;
214 }
215}
216
217int StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances)
218{
219 int attributeOffset = attrib.mOffset % attrib.stride();
220 VertexElement element = { attrib.mType, attrib.mSize, attrib.stride(), attrib.mNormalized, attributeOffset, getWritePosition() };
221 mCache.push_back(element);
222
223 return VertexBufferInterface::storeVertexAttributes(attrib, start, count, instances);
224}
225
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000226}