Extract validation from VertexDataManager.cpp to the API.

We can check for buffer overflow at draw validation time, before
processing any vertex data.

BUG=angle:571

Change-Id: I4f49629b98c17ca28e25baed74cad4ae5341b20f
Reviewed-on: https://chromium-review.googlesource.com/210647
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
diff --git a/src/libGLESv2/renderer/d3d/IndexDataManager.cpp b/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
index 99f2f26..ce46b3d 100644
--- a/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
+++ b/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
@@ -20,42 +20,7 @@
 namespace rx
 {
 
-IndexDataManager::IndexDataManager(Renderer *renderer) : mRenderer(renderer)
-{
-    mStreamingBufferShort = new StreamingIndexBufferInterface(mRenderer);
-    if (!mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT))
-    {
-        delete mStreamingBufferShort;
-        mStreamingBufferShort = NULL;
-    }
-
-    mStreamingBufferInt = new StreamingIndexBufferInterface(mRenderer);
-    if (!mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
-    {
-        delete mStreamingBufferInt;
-        mStreamingBufferInt = NULL;
-    }
-
-    if (!mStreamingBufferShort)
-    {
-        // Make sure both buffers are deleted.
-        delete mStreamingBufferInt;
-        mStreamingBufferInt = NULL;
-
-        ERR("Failed to allocate the streaming index buffer(s).");
-    }
-
-    mCountingBuffer = NULL;
-}
-
-IndexDataManager::~IndexDataManager()
-{
-    delete mStreamingBufferShort;
-    delete mStreamingBufferInt;
-    delete mCountingBuffer;
-}
-
-static void convertIndices(GLenum sourceType, GLenum destinationType, const void *input, GLsizei count, void *output)
+static void ConvertIndices(GLenum sourceType, GLenum destinationType, const void *input, GLsizei count, void *output)
 {
     if (sourceType == GL_UNSIGNED_BYTE)
     {
@@ -94,35 +59,36 @@
     else UNREACHABLE();
 }
 
-template <class IndexType>
-static RangeUI computeRange(const IndexType *indices, GLsizei count)
+IndexDataManager::IndexDataManager(Renderer *renderer)
+    : mRenderer(renderer)
 {
-    unsigned int minIndex = indices[0];
-    unsigned int maxIndex = indices[0];
-
-    for (GLsizei i = 1; i < count; i++)
+    mStreamingBufferShort = new StreamingIndexBufferInterface(mRenderer);
+    if (!mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT))
     {
-        if (minIndex > indices[i]) minIndex = indices[i];
-        if (maxIndex < indices[i]) maxIndex = indices[i];
+        SafeDelete(mStreamingBufferShort);
     }
 
-    return RangeUI(minIndex, maxIndex);
+    mStreamingBufferInt = new StreamingIndexBufferInterface(mRenderer);
+    if (!mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
+    {
+        SafeDelete(mStreamingBufferInt);
+    }
+
+    if (!mStreamingBufferShort)
+    {
+        // Make sure both buffers are deleted.
+        SafeDelete(mStreamingBufferInt);
+        ERR("Failed to allocate the streaming index buffer(s).");
+    }
+
+    mCountingBuffer = NULL;
 }
 
-static RangeUI computeRange(GLenum type, const GLvoid *indices, GLsizei count)
+IndexDataManager::~IndexDataManager()
 {
-    switch (type)
-    {
-      case GL_UNSIGNED_BYTE:
-        return computeRange(static_cast<const GLubyte*>(indices), count);
-      case GL_UNSIGNED_INT:
-        return computeRange(static_cast<const GLuint*>(indices), count);
-      case GL_UNSIGNED_SHORT:
-        return computeRange(static_cast<const GLushort*>(indices), count);
-      default:
-        UNREACHABLE();
-        return RangeUI();
-    }
+    SafeDelete(mStreamingBufferShort);
+    SafeDelete(mStreamingBufferInt);
+    SafeDelete(mCountingBuffer);
 }
 
 GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
@@ -184,9 +150,8 @@
     {
         streamOffset = offset;
 
-        if (!buffer->getIndexRangeCache()->findRange(type, offset, count, &translated->indexRange, NULL))
+        if (!buffer->getIndexRangeCache()->findRange(type, offset, count, NULL, NULL))
         {
-            translated->indexRange = computeRange(type, indices, count);
             buffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, offset);
         }
     }
@@ -194,17 +159,12 @@
     {
         indexBuffer = staticBuffer;
 
-        if (!staticBuffer->getIndexRangeCache()->findRange(type, offset, count, &translated->indexRange, &streamOffset))
+        if (!staticBuffer->getIndexRangeCache()->findRange(type, offset, count, NULL, &streamOffset))
         {
             streamOffset = (offset / typeInfo.bytes) * gl::GetTypeInfo(destinationIndexType).bytes;
-            translated->indexRange = computeRange(type, indices, count);
             staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, streamOffset);
         }
     }
-    else
-    {
-        translated->indexRange = computeRange(type, indices, count);
-    }
 
     // Avoid D3D11's primitive restart index value
     // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx
@@ -263,7 +223,7 @@
             return GL_OUT_OF_MEMORY;
         }
 
-        convertIndices(type, destinationIndexType, staticBuffer ? storage->getData() : indices, convertCount, output);
+        ConvertIndices(type, destinationIndexType, staticBuffer ? storage->getData() : indices, convertCount, output);
 
         if (!indexBuffer->unmapBuffer())
         {