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=geofflang@chromium.org, shannonwoods@chromium.org
ANGLEBUG=467
Review URL=https://codereview.appspot.com/12937045
Test=WebGL CTS 1.0.2
diff --git a/src/libGLESv2/renderer/VertexDataManager.cpp b/src/libGLESv2/renderer/VertexDataManager.cpp
index 9e663e2..30fae19 100644
--- a/src/libGLESv2/renderer/VertexDataManager.cpp
+++ b/src/libGLESv2/renderer/VertexDataManager.cpp
@@ -38,6 +38,20 @@
     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;
+}
+
 static bool DirectStoragePossible(VertexBufferInterface *vb, const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue)
 {
     gl::Buffer *buffer = attrib.mBoundBuffer.get();
@@ -135,7 +149,16 @@
                 }
                 else
                 {
-                    if (!mStreamingBuffer->reserveVertexSpace(attribs[i], count, instances))
+                    int totalCount = StreamingBufferElementCount(attribs[i], count, instances);
+
+                    // [OpenGL ES 3.0.2] section 2.9.4 page 40:
+                    // 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;
                     }
@@ -205,8 +228,9 @@
                 }
                 else
                 {
+                    int totalCount = StreamingBufferElementCount(attribs[i], count, instances);
                     if (!mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0, &outputElementSize) ||
-                        !mStreamingBuffer->storeVertexAttributes(attribs[i], currentValues[i], start, count, instances,
+                        !mStreamingBuffer->storeVertexAttributes(attribs[i], currentValues[i], start, totalCount, instances,
                                                                  &streamOffset))
                     {
                         return GL_OUT_OF_MEMORY;