Optimized prepareVertexData and protect against NULL pointers.
TRAC #14871
Signed-off-by: Daniel Koch
Author: Nicolas Capens
git-svn-id: https://angleproject.googlecode.com/svn/trunk@614 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/VertexDataManager.cpp b/src/libGLESv2/VertexDataManager.cpp
index 098d8f5..4d4f66a 100644
--- a/src/libGLESv2/VertexDataManager.cpp
+++ b/src/libGLESv2/VertexDataManager.cpp
@@ -38,6 +38,11 @@
checkVertexCaps(caps.DeclTypes);
mStreamingBuffer = new StreamingVertexBuffer(mDevice, INITIAL_STREAM_BUFFER_SIZE);
+
+ if (!mStreamingBuffer)
+ {
+ ERR("Failed to allocate the streaming vertex buffer.");
+ }
}
VertexDataManager::~VertexDataManager()
@@ -103,7 +108,11 @@
GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated)
{
- GLenum error = GL_NO_ERROR;
+ if (!mStreamingBuffer)
+ {
+ return GL_OUT_OF_MEMORY;
+ }
+
const VertexAttributeArray &attribs = mContext->getVertexAttributes();
Program *program = mContext->getCurrentProgram();
@@ -112,60 +121,33 @@
translated[attributeIndex].active = (program->getSemanticIndex(attributeIndex) != -1);
}
- // Determine the required storage size per used buffer
+ // Determine the required storage size per used buffer, and invalidate static buffers that don't contain matching attributes
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
- Buffer *buffer = attribs[i].mBoundBuffer.get();
-
- if (translated[i].active && attribs[i].mArrayEnabled && (buffer || attribs[i].mPointer))
+ if (translated[i].active && attribs[i].mArrayEnabled)
{
+ Buffer *buffer = attribs[i].mBoundBuffer.get();
StaticVertexBuffer *staticBuffer = buffer ? buffer->getVertexBuffer() : NULL;
- if (staticBuffer && staticBuffer->size() == 0)
+ if (staticBuffer)
{
- int totalCount = buffer->size() / attribs[i].stride();
- staticBuffer->addRequiredSpace(spaceRequired(attribs[i], totalCount));
- }
- else if (!staticBuffer || staticBuffer->lookupAttribute(attribs[i]) == -1)
- {
- if (mStreamingBuffer)
+ if (staticBuffer->size() == 0)
{
- mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count));
+ int totalCount = buffer->size() / attribs[i].stride();
+ staticBuffer->addRequiredSpace(spaceRequired(attribs[i], totalCount));
}
- }
- }
- }
-
- // Invalidate static buffers if the attribute formats no longer match
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- Buffer *buffer = attribs[i].mBoundBuffer.get();
-
- if (translated[i].active && attribs[i].mArrayEnabled && buffer)
- {
- StaticVertexBuffer *staticBuffer = buffer->getVertexBuffer();
-
- if (staticBuffer && staticBuffer->size() != 0)
- {
- bool matchingAttributes = true;
-
- for (int j = 0; j < MAX_VERTEX_ATTRIBS; j++)
+ else if (staticBuffer->lookupAttribute(attribs[i]) == -1)
{
- if (translated[j].active && attribs[j].mArrayEnabled && attribs[j].mBoundBuffer.get() == buffer)
- {
- if (staticBuffer->lookupAttribute(attribs[j]) == -1)
- {
- matchingAttributes = false;
- break;
- }
- }
- }
-
- if (!matchingAttributes && mStreamingBuffer)
- {
+ // This static buffer doesn't have matching attributes, so fall back to using the streaming buffer
mStreamingBuffer->addRequiredSpaceFor(staticBuffer);
buffer->invalidateStaticData();
- }
+
+ mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count));
+ }
+ }
+ else
+ {
+ mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count));
}
}
}
@@ -173,10 +155,9 @@
// Reserve the required space per used buffer
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
- Buffer *buffer = attribs[i].mBoundBuffer.get();
-
- if (translated[i].active && attribs[i].mArrayEnabled && (buffer || attribs[i].mPointer))
+ if (translated[i].active && attribs[i].mArrayEnabled)
{
+ Buffer *buffer = attribs[i].mBoundBuffer.get();
ArrayVertexBuffer *staticBuffer = buffer ? buffer->getVertexBuffer() : NULL;
ArrayVertexBuffer *vertexBuffer = staticBuffer ? staticBuffer : mStreamingBuffer;