Commit ff989da2 by Jamie Madill

Fix using the incorrect vertex count in instancing drawing using the streaming buffer.

This could cause visual corruption from reading past the end of initialized vertex data. R=shannonwoods@chromium.org ANGLEBUG=467 Review URL=https://codereview.appspot.com/13248043 Test=WebGL CTS 1.0.2
parent 90442f68
......@@ -38,6 +38,20 @@ static int elementsInBuffer(const gl::VertexAttribute &attribute, unsigned int s
return (size - attribute.mOffset % stride + (stride - attribute.typeSize())) / stride;
}
static int StreamingBufferElementCount(const gl::VertexAttribute &attribute, int vertexDrawCount, int instanceDrawCount)
{
// For instanced rendering, we draw "instanceDrawCount" sets of "vertexDrawCount" vertices.
//
// A vertex attribute with a positive divisor loads one instanced vertex for every set of
// non-instanced vertices, and the instanced vertex index advances once every "mDivisor" instances.
if (instanceDrawCount > 0 && attribute.mDivisor > 0)
{
return instanceDrawCount / attribute.mDivisor;
}
return vertexDrawCount;
}
VertexDataManager::VertexDataManager(Renderer *renderer) : mRenderer(renderer)
{
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
......@@ -130,7 +144,16 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[],
}
else
{
if (!mStreamingBuffer->reserveVertexSpace(attribs[i], count, instances))
int totalCount = StreamingBufferElementCount(attribs[i], count, instances);
// Undefined behaviour:
// We can return INVALID_OPERATION if our vertex attribute does not have enough backing data.
if (buffer && elementsInBuffer(attribs[i], buffer->size()) < totalCount)
{
return GL_INVALID_OPERATION;
}
if (!mStreamingBuffer->reserveVertexSpace(attribs[i], totalCount, instances))
{
return GL_OUT_OF_MEMORY;
}
......@@ -200,8 +223,9 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[],
}
else
{
int totalCount = StreamingBufferElementCount(attribs[i], count, instances);
if (!mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0, &outputElementSize) ||
!mStreamingBuffer->storeVertexAttributes(attribs[i], start, count, instances, &streamOffset))
!mStreamingBuffer->storeVertexAttributes(attribs[i], start, totalCount, instances, &streamOffset))
{
return GL_OUT_OF_MEMORY;
}
......
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