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
parent 09c2c1ac
#define MAJOR_VERSION 0 #define MAJOR_VERSION 0
#define MINOR_VERSION 0 #define MINOR_VERSION 0
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 609 #define BUILD_REVISION 614
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -30,11 +30,23 @@ IndexDataManager::IndexDataManager(Context *context, IDirect3DDevice9 *device) : ...@@ -30,11 +30,23 @@ IndexDataManager::IndexDataManager(Context *context, IDirect3DDevice9 *device) :
if (context->supports32bitIndices()) if (context->supports32bitIndices())
{ {
mStreamingBufferInt = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX32); mStreamingBufferInt = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX32);
if (!mStreamingBufferInt)
{
// Don't leave it in a half-initialized state
delete mStreamingBufferShort;
mStreamingBufferShort = NULL;
}
} }
else else
{ {
mStreamingBufferInt = NULL; mStreamingBufferInt = NULL;
} }
if (!mStreamingBufferShort)
{
ERR("Failed to allocate the streaming index buffer(s).");
}
} }
IndexDataManager::~IndexDataManager() IndexDataManager::~IndexDataManager()
...@@ -98,6 +110,11 @@ void computeRange(GLenum type, const void *indices, GLsizei count, GLuint *minIn ...@@ -98,6 +110,11 @@ void computeRange(GLenum type, const void *indices, GLsizei count, GLuint *minIn
GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated) GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated)
{ {
if (!mStreamingBufferShort)
{
return GL_OUT_OF_MEMORY;
}
D3DFORMAT format = (type == GL_UNSIGNED_INT) ? D3DFMT_INDEX32 : D3DFMT_INDEX16; D3DFORMAT format = (type == GL_UNSIGNED_INT) ? D3DFMT_INDEX32 : D3DFMT_INDEX16;
intptr_t offset = reinterpret_cast<intptr_t>(indices); intptr_t offset = reinterpret_cast<intptr_t>(indices);
bool alignedOffset = false; bool alignedOffset = false;
......
...@@ -38,6 +38,11 @@ VertexDataManager::VertexDataManager(Context *context, IDirect3DDevice9 *device) ...@@ -38,6 +38,11 @@ VertexDataManager::VertexDataManager(Context *context, IDirect3DDevice9 *device)
checkVertexCaps(caps.DeclTypes); checkVertexCaps(caps.DeclTypes);
mStreamingBuffer = new StreamingVertexBuffer(mDevice, INITIAL_STREAM_BUFFER_SIZE); mStreamingBuffer = new StreamingVertexBuffer(mDevice, INITIAL_STREAM_BUFFER_SIZE);
if (!mStreamingBuffer)
{
ERR("Failed to allocate the streaming vertex buffer.");
}
} }
VertexDataManager::~VertexDataManager() VertexDataManager::~VertexDataManager()
...@@ -103,7 +108,11 @@ UINT VertexDataManager::writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLin ...@@ -103,7 +108,11 @@ UINT VertexDataManager::writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLin
GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated) 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(); const VertexAttributeArray &attribs = mContext->getVertexAttributes();
Program *program = mContext->getCurrentProgram(); Program *program = mContext->getCurrentProgram();
...@@ -112,60 +121,33 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat ...@@ -112,60 +121,33 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat
translated[attributeIndex].active = (program->getSemanticIndex(attributeIndex) != -1); 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++) for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{ {
Buffer *buffer = attribs[i].mBoundBuffer.get(); if (translated[i].active && attribs[i].mArrayEnabled)
if (translated[i].active && attribs[i].mArrayEnabled && (buffer || attribs[i].mPointer))
{ {
Buffer *buffer = attribs[i].mBoundBuffer.get();
StaticVertexBuffer *staticBuffer = buffer ? buffer->getVertexBuffer() : NULL; 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));
} }
} else if (staticBuffer->lookupAttribute(attribs[i]) == -1)
}
}
// 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++)
{
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); mStreamingBuffer->addRequiredSpaceFor(staticBuffer);
buffer->invalidateStaticData(); buffer->invalidateStaticData();
}
mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count));
}
}
else
{
mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count));
} }
} }
} }
...@@ -173,10 +155,9 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat ...@@ -173,10 +155,9 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat
// Reserve the required space per used buffer // Reserve the required space per used buffer
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{ {
Buffer *buffer = attribs[i].mBoundBuffer.get(); if (translated[i].active && attribs[i].mArrayEnabled)
if (translated[i].active && attribs[i].mArrayEnabled && (buffer || attribs[i].mPointer))
{ {
Buffer *buffer = attribs[i].mBoundBuffer.get();
ArrayVertexBuffer *staticBuffer = buffer ? buffer->getVertexBuffer() : NULL; ArrayVertexBuffer *staticBuffer = buffer ? buffer->getVertexBuffer() : NULL;
ArrayVertexBuffer *vertexBuffer = staticBuffer ? staticBuffer : mStreamingBuffer; ArrayVertexBuffer *vertexBuffer = staticBuffer ? staticBuffer : mStreamingBuffer;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment