blob: 16e14865112d16b74ed30e0761ecae18b10d6e3b [file] [log] [blame]
shannon.woods@transgaming.combdf2d802013-02-28 23:16:20 +00001#include "precompiled.h"
daniel@transgaming.com29787c32012-12-20 20:55:48 +00002//
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
daniel@transgaming.comdcfb1f72012-12-20 20:57:03 +00008// VertexBuffer.cpp: Defines the abstract VertexBuffer class and VertexBufferInterface
9// class with derivations, classes that perform graphics API agnostic vertex buffer operations.
daniel@transgaming.com29787c32012-12-20 20:55:48 +000010
11#include "libGLESv2/renderer/VertexBuffer.h"
shannon.woods@transgaming.comd2811d62013-02-28 23:11:19 +000012#include "libGLESv2/renderer/Renderer.h"
13#include "libGLESv2/Context.h"
daniel@transgaming.com29787c32012-12-20 20:55:48 +000014
daniel@transgaming.com29787c32012-12-20 20:55:48 +000015namespace rx
16{
17
daniel@transgaming.comdcfb1f72012-12-20 20:57:03 +000018unsigned int VertexBuffer::mNextSerial = 1;
19
20VertexBuffer::VertexBuffer()
21{
22 updateSerial();
23}
24
25VertexBuffer::~VertexBuffer()
26{
27}
28
29void VertexBuffer::updateSerial()
30{
31 mSerial = mNextSerial++;
32}
33
34unsigned int VertexBuffer::getSerial() const
35{
36 return mSerial;
37}
38
daniel@transgaming.com4150d362012-12-20 21:07:43 +000039VertexBufferInterface::VertexBufferInterface(rx::Renderer *renderer, bool dynamic) : mRenderer(renderer)
daniel@transgaming.com29787c32012-12-20 20:55:48 +000040{
daniel@transgaming.com4150d362012-12-20 21:07:43 +000041 mDynamic = dynamic;
daniel@transgaming.coma41d07f2012-12-20 20:55:57 +000042 mWritePosition = 0;
daniel@transgaming.com4150d362012-12-20 21:07:43 +000043 mReservedSpace = 0;
44
45 mVertexBuffer = renderer->createVertexBuffer();
daniel@transgaming.com29787c32012-12-20 20:55:48 +000046}
47
daniel@transgaming.come4e45062012-12-20 20:56:53 +000048VertexBufferInterface::~VertexBufferInterface()
daniel@transgaming.com29787c32012-12-20 20:55:48 +000049{
daniel@transgaming.com4150d362012-12-20 21:07:43 +000050 delete mVertexBuffer;
daniel@transgaming.com29787c32012-12-20 20:55:48 +000051}
52
daniel@transgaming.come4e45062012-12-20 20:56:53 +000053unsigned int VertexBufferInterface::getSerial() const
daniel@transgaming.com29787c32012-12-20 20:55:48 +000054{
daniel@transgaming.com4150d362012-12-20 21:07:43 +000055 return mVertexBuffer->getSerial();
daniel@transgaming.com29787c32012-12-20 20:55:48 +000056}
57
daniel@transgaming.com4150d362012-12-20 21:07:43 +000058unsigned int VertexBufferInterface::getBufferSize() const
daniel@transgaming.com29787c32012-12-20 20:55:48 +000059{
daniel@transgaming.com4150d362012-12-20 21:07:43 +000060 return mVertexBuffer->getBufferSize();
daniel@transgaming.com29787c32012-12-20 20:55:48 +000061}
62
daniel@transgaming.com4150d362012-12-20 21:07:43 +000063bool VertexBufferInterface::setBufferSize(unsigned int size)
daniel@transgaming.com29787c32012-12-20 20:55:48 +000064{
daniel@transgaming.com4150d362012-12-20 21:07:43 +000065 if (mVertexBuffer->getBufferSize() == 0)
66 {
67 return mVertexBuffer->initialize(size, mDynamic);
68 }
69 else
70 {
71 return mVertexBuffer->setBufferSize(size);
72 }
daniel@transgaming.com29787c32012-12-20 20:55:48 +000073}
74
daniel@transgaming.com4150d362012-12-20 21:07:43 +000075unsigned int VertexBufferInterface::getWritePosition() const
daniel@transgaming.com29787c32012-12-20 20:55:48 +000076{
daniel@transgaming.com4150d362012-12-20 21:07:43 +000077 return mWritePosition;
78}
79
80void VertexBufferInterface::setWritePosition(unsigned int writePosition)
81{
82 mWritePosition = writePosition;
83}
84
85bool VertexBufferInterface::discard()
86{
87 return mVertexBuffer->discard();
88}
89
90int VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances)
91{
92 if (!reserveSpace(mReservedSpace))
93 {
94 return -1;
95 }
96 mReservedSpace = 0;
97
98 if (!mVertexBuffer->storeVertexAttributes(attrib, start, count, instances, mWritePosition))
99 {
100 return -1;
101 }
102
103 int oldWritePos = static_cast<int>(mWritePosition);
104 mWritePosition += mVertexBuffer->getSpaceRequired(attrib, count, instances);
105
106 return oldWritePos;
107}
108
109int VertexBufferInterface::storeRawData(const void* data, unsigned int size)
110{
111 if (!reserveSpace(mReservedSpace))
112 {
113 return -1;
114 }
115 mReservedSpace = 0;
116
117 if (!mVertexBuffer->storeRawData(data, size, mWritePosition))
118 {
119 return -1;
120 }
121
122 int oldWritePos = static_cast<int>(mWritePosition);
123 mWritePosition += size;
124
125 return oldWritePos;
126}
127
128void VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances)
129{
130 mReservedSpace += mVertexBuffer->getSpaceRequired(attribute, count, instances);
131}
132
133void VertexBufferInterface::reserveRawDataSpace(unsigned int size)
134{
135 mReservedSpace += size;
136}
137
138VertexBuffer* VertexBufferInterface::getVertexBuffer() const
139{
140 return mVertexBuffer;
141}
142
143
144StreamingVertexBufferInterface::StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true)
145{
146 setBufferSize(initialSize);
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000147}
148
daniel@transgaming.come4e45062012-12-20 20:56:53 +0000149StreamingVertexBufferInterface::~StreamingVertexBufferInterface()
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000150{
151}
152
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000153bool StreamingVertexBufferInterface::reserveSpace(unsigned int size)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000154{
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000155 bool result = true;
156 unsigned int curBufferSize = getBufferSize();
157 if (size > curBufferSize)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000158 {
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000159 result = setBufferSize(std::max(size, 3 * curBufferSize / 2));
160 setWritePosition(0);
161 }
162 else if (getWritePosition() + size > curBufferSize)
163 {
164 if (!discard())
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000165 {
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000166 return false;
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000167 }
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000168 setWritePosition(0);
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000169 }
170
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000171 return result;
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000172}
173
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000174StaticVertexBufferInterface::StaticVertexBufferInterface(rx::Renderer *renderer) : VertexBufferInterface(renderer, false)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000175{
176}
177
daniel@transgaming.come4e45062012-12-20 20:56:53 +0000178StaticVertexBufferInterface::~StaticVertexBufferInterface()
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000179{
180}
181
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000182int StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attribute)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000183{
184 for (unsigned int element = 0; element < mCache.size(); element++)
185 {
186 if (mCache[element].type == attribute.mType &&
187 mCache[element].size == attribute.mSize &&
188 mCache[element].stride == attribute.stride() &&
189 mCache[element].normalized == attribute.mNormalized)
190 {
191 if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride())
192 {
193 return mCache[element].streamOffset;
194 }
195 }
196 }
197
198 return -1;
199}
200
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000201bool StaticVertexBufferInterface::reserveSpace(unsigned int size)
202{
203 unsigned int curSize = getBufferSize();
204 if (curSize == 0)
205 {
206 setBufferSize(size);
207 return true;
208 }
209 else if (curSize >= size)
210 {
211 return true;
212 }
213 else
214 {
215 UNREACHABLE(); // Static vertex buffers can't be resized
216 return false;
217 }
218}
219
220int StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances)
221{
222 int attributeOffset = attrib.mOffset % attrib.stride();
223 VertexElement element = { attrib.mType, attrib.mSize, attrib.stride(), attrib.mNormalized, attributeOffset, getWritePosition() };
224 mCache.push_back(element);
225
226 return VertexBufferInterface::storeVertexAttributes(attrib, start, count, instances);
227}
228
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000229}