Add better error checking on buffer updates

TRAC #12186 Signed-off-by: Nicolas Capens Signed-off-by: Daniel Koch Author: Andrew Lewycky git-svn-id: https://angleproject.googlecode.com/svn/trunk@266 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent c828b149
......@@ -1967,11 +1967,16 @@ void Context::applyVertexBuffer(const TranslatedIndexData &indexInfo)
}
// Applies the indices and element array bindings to the Direct3D 9 device
TranslatedIndexData Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type)
GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
{
TranslatedIndexData indexInfo = mIndexDataManager->preRenderValidate(mode, type, count, getBuffer(mState.elementArrayBuffer), indices);
mBufferBackEnd->setupIndicesPreDraw(indexInfo);
return indexInfo;
GLenum error = mIndexDataManager->preRenderValidate(mode, type, count, getBuffer(mState.elementArrayBuffer), indices, indexInfo);
if (error == GL_NO_ERROR)
{
mBufferBackEnd->setupIndicesPreDraw(*indexInfo);
}
return error;
}
// Applies the shaders and shader constants to the Direct3D 9 device
......@@ -2456,7 +2461,14 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void*
}
applyState(mode);
TranslatedIndexData indexInfo = applyIndexBuffer(indices, count, mode, type);
TranslatedIndexData indexInfo;
GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);
if (err != GL_NO_ERROR)
{
return error(err);
}
applyVertexBuffer(indexInfo);
applyShaders();
applyTextures();
......
......@@ -353,7 +353,7 @@ class Context
void applyState(GLenum drawMode);
void applyVertexBuffer(GLint first, GLsizei count);
void applyVertexBuffer(const TranslatedIndexData &indexInfo);
TranslatedIndexData applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type);
GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
void applyShaders();
void applyTextures();
......
......@@ -70,14 +70,24 @@ void copyIndices(const InputIndexType *in, GLsizei count, OutputIndexType *out,
}
TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices)
GLenum IndexDataManager::preRenderValidate(GLenum mode, GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated)
{
ASSERT(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT);
ASSERT(count > 0);
TranslatedIndexData translated;
if (arrayElementBuffer != NULL)
{
GLsizei offset = reinterpret_cast<GLsizei>(indices);
if (typeSize(type) * count + offset > static_cast<std::size_t>(arrayElementBuffer->size()))
{
return GL_INVALID_OPERATION;
}
indices = static_cast<const GLubyte*>(arrayElementBuffer->data()) + offset;
}
translated.count = count;
translated->count = count;
std::size_t requiredSpace = spaceRequired(type, count);
......@@ -86,23 +96,18 @@ TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type
size_t offset;
void *output = streamIb->map(requiredSpace, &offset);
translated.buffer = streamIb;
translated.offset = offset;
translated.indexSize = indexSize(type);
translated.indices = output;
translated->buffer = streamIb;
translated->offset = offset;
translated->indexSize = indexSize(type);
if (arrayElementBuffer != NULL)
{
indices = static_cast<const GLubyte*>(arrayElementBuffer->data()) + reinterpret_cast<GLsizei>(indices);
}
translated->indices = output;
if (type == GL_UNSIGNED_BYTE)
{
const GLubyte *in = static_cast<const GLubyte*>(indices);
GLushort *out = static_cast<GLushort*>(output);
copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex);
copyIndices(in, count, out, &translated->minIndex, &translated->maxIndex);
}
else if (type == GL_UNSIGNED_INT)
{
......@@ -112,7 +117,7 @@ TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type
{
GLuint *out = static_cast<GLuint*>(output);
copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex);
copyIndices(in, count, out, &translated->minIndex, &translated->maxIndex);
}
else
{
......@@ -120,7 +125,7 @@ TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type
GLushort *out = static_cast<GLushort*>(output);
copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex);
copyIndices(in, count, out, &translated->minIndex, &translated->maxIndex);
}
}
else
......@@ -128,12 +133,12 @@ TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type
const GLushort *in = static_cast<const GLushort*>(indices);
GLushort *out = static_cast<GLushort*>(output);
copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex);
copyIndices(in, count, out, &translated->minIndex, &translated->maxIndex);
}
streamIb->unmap();
return translated;
return GL_NO_ERROR;
}
std::size_t IndexDataManager::indexSize(GLenum type) const
......@@ -141,6 +146,17 @@ std::size_t IndexDataManager::indexSize(GLenum type) const
return (type == GL_UNSIGNED_INT && mIntIndicesSupported) ? sizeof(GLuint) : sizeof(GLushort);
}
std::size_t IndexDataManager::typeSize(GLenum type) const
{
switch (type)
{
case GL_UNSIGNED_INT: return sizeof(GLuint);
case GL_UNSIGNED_SHORT: return sizeof(GLushort);
default: UNREACHABLE();
case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
}
}
std::size_t IndexDataManager::spaceRequired(GLenum type, GLsizei count) const
{
return (count + 1) * indexSize(type); // +1 because we always leave an extra for line loops
......
......@@ -45,9 +45,10 @@ class IndexDataManager
IndexDataManager(Context *context, BufferBackEnd *backend);
~IndexDataManager();
TranslatedIndexData preRenderValidate(GLenum mode, GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices);
GLenum preRenderValidate(GLenum mode, GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
private:
std::size_t IndexDataManager::typeSize(GLenum type) const;
std::size_t IndexDataManager::indexSize(GLenum type) const;
std::size_t spaceRequired(GLenum type, GLsizei count) const;
TranslatedIndexBuffer *prepareIndexBuffer(GLenum type, std::size_t requiredSpace);
......
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