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) ...@@ -1967,11 +1967,16 @@ void Context::applyVertexBuffer(const TranslatedIndexData &indexInfo)
} }
// Applies the indices and element array bindings to the Direct3D 9 device // 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); GLenum error = mIndexDataManager->preRenderValidate(mode, type, count, getBuffer(mState.elementArrayBuffer), indices, indexInfo);
mBufferBackEnd->setupIndicesPreDraw(indexInfo);
return indexInfo; if (error == GL_NO_ERROR)
{
mBufferBackEnd->setupIndicesPreDraw(*indexInfo);
}
return error;
} }
// Applies the shaders and shader constants to the Direct3D 9 device // 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* ...@@ -2456,7 +2461,14 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void*
} }
applyState(mode); 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); applyVertexBuffer(indexInfo);
applyShaders(); applyShaders();
applyTextures(); applyTextures();
......
...@@ -353,7 +353,7 @@ class Context ...@@ -353,7 +353,7 @@ class Context
void applyState(GLenum drawMode); void applyState(GLenum drawMode);
void applyVertexBuffer(GLint first, GLsizei count); void applyVertexBuffer(GLint first, GLsizei count);
void applyVertexBuffer(const TranslatedIndexData &indexInfo); 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 applyShaders();
void applyTextures(); void applyTextures();
......
...@@ -70,14 +70,24 @@ void copyIndices(const InputIndexType *in, GLsizei count, OutputIndexType *out, ...@@ -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(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT);
ASSERT(count > 0); 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); std::size_t requiredSpace = spaceRequired(type, count);
...@@ -86,23 +96,18 @@ TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type ...@@ -86,23 +96,18 @@ TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type
size_t offset; size_t offset;
void *output = streamIb->map(requiredSpace, &offset); void *output = streamIb->map(requiredSpace, &offset);
translated.buffer = streamIb; translated->buffer = streamIb;
translated.offset = offset; translated->offset = offset;
translated.indexSize = indexSize(type); translated->indexSize = indexSize(type);
translated.indices = output;
if (arrayElementBuffer != NULL) translated->indices = output;
{
indices = static_cast<const GLubyte*>(arrayElementBuffer->data()) + reinterpret_cast<GLsizei>(indices);
}
if (type == GL_UNSIGNED_BYTE) if (type == GL_UNSIGNED_BYTE)
{ {
const GLubyte *in = static_cast<const GLubyte*>(indices); const GLubyte *in = static_cast<const GLubyte*>(indices);
GLushort *out = static_cast<GLushort*>(output); 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) else if (type == GL_UNSIGNED_INT)
{ {
...@@ -112,7 +117,7 @@ TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type ...@@ -112,7 +117,7 @@ TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type
{ {
GLuint *out = static_cast<GLuint*>(output); GLuint *out = static_cast<GLuint*>(output);
copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex); copyIndices(in, count, out, &translated->minIndex, &translated->maxIndex);
} }
else else
{ {
...@@ -120,7 +125,7 @@ TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type ...@@ -120,7 +125,7 @@ TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type
GLushort *out = static_cast<GLushort*>(output); GLushort *out = static_cast<GLushort*>(output);
copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex); copyIndices(in, count, out, &translated->minIndex, &translated->maxIndex);
} }
} }
else else
...@@ -128,12 +133,12 @@ TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type ...@@ -128,12 +133,12 @@ TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type
const GLushort *in = static_cast<const GLushort*>(indices); const GLushort *in = static_cast<const GLushort*>(indices);
GLushort *out = static_cast<GLushort*>(output); GLushort *out = static_cast<GLushort*>(output);
copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex); copyIndices(in, count, out, &translated->minIndex, &translated->maxIndex);
} }
streamIb->unmap(); streamIb->unmap();
return translated; return GL_NO_ERROR;
} }
std::size_t IndexDataManager::indexSize(GLenum type) const std::size_t IndexDataManager::indexSize(GLenum type) const
...@@ -141,6 +146,17 @@ 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); 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 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 return (count + 1) * indexSize(type); // +1 because we always leave an extra for line loops
......
...@@ -45,9 +45,10 @@ class IndexDataManager ...@@ -45,9 +45,10 @@ class IndexDataManager
IndexDataManager(Context *context, BufferBackEnd *backend); IndexDataManager(Context *context, BufferBackEnd *backend);
~IndexDataManager(); ~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: private:
std::size_t IndexDataManager::typeSize(GLenum type) const;
std::size_t IndexDataManager::indexSize(GLenum type) const; std::size_t IndexDataManager::indexSize(GLenum type) const;
std::size_t spaceRequired(GLenum type, GLsizei count) const; std::size_t spaceRequired(GLenum type, GLsizei count) const;
TranslatedIndexBuffer *prepareIndexBuffer(GLenum type, std::size_t requiredSpace); 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