blob: 509dc532a0c2fe5888ee97e661d3ab32aa16004b [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
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000109void VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances)
110{
111 mReservedSpace += mVertexBuffer->getSpaceRequired(attribute, count, instances);
112}
113
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000114VertexBuffer* VertexBufferInterface::getVertexBuffer() const
115{
116 return mVertexBuffer;
117}
118
119
120StreamingVertexBufferInterface::StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true)
121{
122 setBufferSize(initialSize);
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000123}
124
daniel@transgaming.come4e45062012-12-20 20:56:53 +0000125StreamingVertexBufferInterface::~StreamingVertexBufferInterface()
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000126{
127}
128
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000129bool StreamingVertexBufferInterface::reserveSpace(unsigned int size)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000130{
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000131 bool result = true;
132 unsigned int curBufferSize = getBufferSize();
133 if (size > curBufferSize)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000134 {
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000135 result = setBufferSize(std::max(size, 3 * curBufferSize / 2));
136 setWritePosition(0);
137 }
138 else if (getWritePosition() + size > curBufferSize)
139 {
140 if (!discard())
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000141 {
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000142 return false;
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000143 }
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000144 setWritePosition(0);
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000145 }
146
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000147 return result;
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000148}
149
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000150StaticVertexBufferInterface::StaticVertexBufferInterface(rx::Renderer *renderer) : VertexBufferInterface(renderer, false)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000151{
152}
153
daniel@transgaming.come4e45062012-12-20 20:56:53 +0000154StaticVertexBufferInterface::~StaticVertexBufferInterface()
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000155{
156}
157
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000158int StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attribute)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000159{
160 for (unsigned int element = 0; element < mCache.size(); element++)
161 {
162 if (mCache[element].type == attribute.mType &&
163 mCache[element].size == attribute.mSize &&
164 mCache[element].stride == attribute.stride() &&
shannon.woods%transgaming.com@gtempaccount.com8de4e6a2013-04-13 03:37:44 +0000165 mCache[element].normalized == attribute.mNormalized &&
166 mCache[element].pureInteger == attribute.mPureInteger)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000167 {
168 if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride())
169 {
170 return mCache[element].streamOffset;
171 }
172 }
173 }
174
175 return -1;
176}
177
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000178bool StaticVertexBufferInterface::reserveSpace(unsigned int size)
179{
180 unsigned int curSize = getBufferSize();
181 if (curSize == 0)
182 {
183 setBufferSize(size);
184 return true;
185 }
186 else if (curSize >= size)
187 {
188 return true;
189 }
190 else
191 {
192 UNREACHABLE(); // Static vertex buffers can't be resized
193 return false;
194 }
195}
196
197int StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances)
198{
199 int attributeOffset = attrib.mOffset % attrib.stride();
shannon.woods%transgaming.com@gtempaccount.com8de4e6a2013-04-13 03:37:44 +0000200 VertexElement element = { attrib.mType, attrib.mSize, attrib.stride(), attrib.mNormalized, attrib.mPureInteger, attributeOffset, getWritePosition() };
daniel@transgaming.com4150d362012-12-20 21:07:43 +0000201 mCache.push_back(element);
202
203 return VertexBufferInterface::storeVertexAttributes(attrib, start, count, instances);
204}
205
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000206}