Use Range type for index ranges.

This compacts a lot of parameter passing. Refactoring patch only.

BUG=angle:571

Change-Id: Ic918478d0c6b81093bfea6154ce0f6bf1d2b5be2
Reviewed-on: https://chromium-review.googlesource.com/210645
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/common/mathutil.h b/src/common/mathutil.h
index 02b44c2..ffcb908 100644
--- a/src/common/mathutil.h
+++ b/src/common/mathutil.h
@@ -503,15 +503,21 @@
 namespace rx
 {
 
+template <typename T>
 struct Range
 {
     Range() {}
-    Range(int lo, int hi) : start(lo), end(hi) { ASSERT(lo <= hi); }
+    Range(T lo, T hi) : start(lo), end(hi) { ASSERT(lo <= hi); }
 
-    int start;
-    int end;
+    T start;
+    T end;
+
+    T length() const { return end - start; }
 };
 
+typedef Range<int> RangeI;
+typedef Range<unsigned int> RangeUI;
+
 template <typename T>
 T roundUp(const T value, const T alignment)
 {
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index bccfd14..81ddeac 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -1832,8 +1832,10 @@
         return gl::error(err);
     }
 
-    GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
-    err = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(), mState.getVertexAttribCurrentValues(), indexInfo.minIndex, vertexCount, instances);
+    GLsizei vertexCount = indexInfo.indexRange.length() + 1;
+    err = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(),
+                                       mState.getVertexAttribCurrentValues(),
+                                       indexInfo.indexRange.start, vertexCount, instances);
     if (err != GL_NO_ERROR)
     {
         return gl::error(err);
diff --git a/src/libGLESv2/renderer/IndexRangeCache.cpp b/src/libGLESv2/renderer/IndexRangeCache.cpp
index 4fdb0ca..1f6a16f 100644
--- a/src/libGLESv2/renderer/IndexRangeCache.cpp
+++ b/src/libGLESv2/renderer/IndexRangeCache.cpp
@@ -16,10 +16,10 @@
 namespace rx
 {
 
-void IndexRangeCache::addRange(GLenum type, unsigned int offset, GLsizei count, unsigned int minIdx, unsigned int maxIdx,
+void IndexRangeCache::addRange(GLenum type, unsigned int offset, GLsizei count, const RangeUI &range,
                                unsigned int streamOffset)
 {
-    mIndexRangeCache[IndexRange(type, offset, count)] = IndexBounds(minIdx, maxIdx, streamOffset);
+    mIndexRangeCache[IndexRange(type, offset, count)] = IndexBounds(range, streamOffset);
 }
 
 void IndexRangeCache::invalidateRange(unsigned int offset, unsigned int size)
@@ -44,21 +44,19 @@
     }
 }
 
-bool IndexRangeCache::findRange(GLenum type, unsigned int offset, GLsizei count, unsigned int *outMinIndex,
-                                unsigned int *outMaxIndex, unsigned int *outStreamOffset) const
+bool IndexRangeCache::findRange(GLenum type, unsigned int offset, GLsizei count,
+                                RangeUI *outRange, unsigned int *outStreamOffset) const
 {
     IndexRangeMap::const_iterator i = mIndexRangeCache.find(IndexRange(type, offset, count));
     if (i != mIndexRangeCache.end())
     {
-        if (outMinIndex)     *outMinIndex = i->second.minIndex;
-        if (outMaxIndex)     *outMaxIndex = i->second.maxIndex;
+        if (outRange)        *outRange = i->second.range;
         if (outStreamOffset) *outStreamOffset = i->second.streamOffset;
         return true;
     }
     else
     {
-        if (outMinIndex)     *outMinIndex = 0;
-        if (outMaxIndex)     *outMaxIndex = 0;
+        if (outRange)        *outRange = RangeUI(0, 0);
         if (outStreamOffset) *outStreamOffset = 0;
         return false;
     }
@@ -85,12 +83,13 @@
 }
 
 IndexRangeCache::IndexBounds::IndexBounds()
-    : minIndex(0), maxIndex(0), streamOffset(0)
+    : range(0, 0),
+      streamOffset(0)
 {
 }
 
-IndexRangeCache::IndexBounds::IndexBounds(unsigned int minIdx, unsigned int maxIdx, unsigned int offset)
-    : minIndex(minIdx), maxIndex(maxIdx), streamOffset(offset)
+IndexRangeCache::IndexBounds::IndexBounds(const RangeUI &rangeIn, unsigned int offset)
+    : range(rangeIn), streamOffset(offset)
 {
 }
 
diff --git a/src/libGLESv2/renderer/IndexRangeCache.h b/src/libGLESv2/renderer/IndexRangeCache.h
index 4318e2b..b552847 100644
--- a/src/libGLESv2/renderer/IndexRangeCache.h
+++ b/src/libGLESv2/renderer/IndexRangeCache.h
@@ -11,6 +11,7 @@
 #define LIBGLESV2_RENDERER_INDEXRANGECACHE_H_
 
 #include "common/angleutils.h"
+#include "common/mathutil.h"
 #include <map>
 
 namespace rx
@@ -19,10 +20,10 @@
 class IndexRangeCache
 {
   public:
-    void addRange(GLenum type, unsigned int offset, GLsizei count, unsigned int minIdx, unsigned int maxIdx,
+    void addRange(GLenum type, unsigned int offset, GLsizei count, const RangeUI &range,
                   unsigned int streamOffset);
-    bool findRange(GLenum type, unsigned int offset, GLsizei count, unsigned int *outMinIndex,
-                   unsigned int *outMaxIndex, unsigned int *outStreamOffset) const;
+    bool findRange(GLenum type, unsigned int offset, GLsizei count, RangeUI *rangeOut,
+                   unsigned int *outStreamOffset) const;
 
     void invalidateRange(unsigned int offset, unsigned int size);
     void clear();
@@ -42,12 +43,11 @@
 
     struct IndexBounds
     {
-        unsigned int minIndex;
-        unsigned int maxIndex;
+        RangeUI range;
         unsigned int streamOffset;
 
         IndexBounds();
-        IndexBounds(unsigned int minIdx, unsigned int maxIdx, unsigned int offset);
+        IndexBounds(const RangeUI &range, unsigned int offset);
     };
 
     typedef std::map<IndexRange, IndexBounds> IndexRangeMap;
diff --git a/src/libGLESv2/renderer/d3d/IndexDataManager.cpp b/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
index 98716c1..45d7d37 100644
--- a/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
+++ b/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
@@ -95,33 +95,34 @@
 }
 
 template <class IndexType>
-static void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+static RangeUI computeRange(const IndexType *indices, GLsizei count)
 {
-    *minIndex = indices[0];
-    *maxIndex = indices[0];
+    unsigned int minIndex = indices[0];
+    unsigned int maxIndex = indices[0];
 
-    for (GLsizei i = 0; i < count; i++)
+    for (GLsizei i = 1; i < count; i++)
     {
-        if (*minIndex > indices[i]) *minIndex = indices[i];
-        if (*maxIndex < indices[i]) *maxIndex = indices[i];
+        if (minIndex > indices[i]) minIndex = indices[i];
+        if (maxIndex < indices[i]) maxIndex = indices[i];
     }
+
+    return RangeUI(minIndex, maxIndex);
 }
 
-static void computeRange(GLenum type, const GLvoid *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+static RangeUI computeRange(GLenum type, const GLvoid *indices, GLsizei count)
 {
-    if (type == GL_UNSIGNED_BYTE)
+    switch (type)
     {
-        computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);
+      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();
     }
-    else if (type == GL_UNSIGNED_INT)
-    {
-        computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex);
-    }
-    else if (type == GL_UNSIGNED_SHORT)
-    {
-        computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);
-    }
-    else UNREACHABLE();
 }
 
 GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
@@ -183,35 +184,31 @@
     {
         streamOffset = offset;
 
-        if (!storage->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex,
-                                                     &translated->maxIndex, NULL))
+        if (!storage->getIndexRangeCache()->findRange(type, offset, count, &translated->indexRange, NULL))
         {
-            computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
-            storage->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
-                                                   translated->maxIndex, offset);
+            translated->indexRange = computeRange(type, indices, count);
+            storage->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, offset);
         }
     }
     else if (staticBuffer && staticBuffer->getBufferSize() != 0 && staticBuffer->getIndexType() == type && alignedOffset)
     {
         indexBuffer = staticBuffer;
 
-        if (!staticBuffer->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex,
-                                                           &translated->maxIndex, &streamOffset))
+        if (!staticBuffer->getIndexRangeCache()->findRange(type, offset, count, &translated->indexRange, &streamOffset))
         {
             streamOffset = (offset / typeInfo.bytes) * gl::GetTypeInfo(destinationIndexType).bytes;
-            computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
-            staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
-                                                         translated->maxIndex, streamOffset);
+            translated->indexRange = computeRange(type, indices, count);
+            staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, streamOffset);
         }
     }
     else
     {
-        computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
+        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
-    if (translated->maxIndex == 0xFFFF && type == GL_UNSIGNED_SHORT && mRenderer->getMajorShaderModel() > 3)
+    if (translated->indexRange.end == 0xFFFF && type == GL_UNSIGNED_SHORT && mRenderer->getMajorShaderModel() > 3)
     {
         destinationIndexType = GL_UNSIGNED_INT;
         directStorage = false;
@@ -277,8 +274,7 @@
         if (staticBuffer)
         {
             streamOffset = (offset / typeInfo.bytes) * destTypeInfo.bytes;
-            staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
-                                                         translated->maxIndex, streamOffset);
+            staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, streamOffset);
         }
     }
 
diff --git a/src/libGLESv2/renderer/d3d/IndexDataManager.h b/src/libGLESv2/renderer/d3d/IndexDataManager.h
index b27c223..1321465 100644
--- a/src/libGLESv2/renderer/d3d/IndexDataManager.h
+++ b/src/libGLESv2/renderer/d3d/IndexDataManager.h
@@ -11,6 +11,7 @@
 #define LIBGLESV2_INDEXDATAMANAGER_H_
 
 #include "common/angleutils.h"
+#include "common/mathutil.h"
 
 namespace
 {
@@ -32,8 +33,7 @@
 
 struct TranslatedIndexData
 {
-    unsigned int minIndex;
-    unsigned int maxIndex;
+    RangeUI indexRange;
     unsigned int startIndex;
     unsigned int startOffset;   // In bytes
 
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
index d83910d..2c2d776 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
@@ -1067,21 +1067,23 @@
 void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
                               gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances)
 {
+    int minIndex = static_cast<int>(indexInfo.indexRange.start);
+
     if (mode == GL_LINE_LOOP)
     {
-        drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer);
+        drawLineLoop(count, type, indices, minIndex, elementArrayBuffer);
     }
     else if (mode == GL_TRIANGLE_FAN)
     {
-        drawTriangleFan(count, type, indices, indexInfo.minIndex, elementArrayBuffer, instances);
+        drawTriangleFan(count, type, indices, minIndex, elementArrayBuffer, instances);
     }
     else if (instances > 0)
     {
-        mDeviceContext->DrawIndexedInstanced(count, instances, 0, -static_cast<int>(indexInfo.minIndex), 0);
+        mDeviceContext->DrawIndexedInstanced(count, instances, 0, -minIndex, 0);
     }
     else
     {
-        mDeviceContext->DrawIndexed(count, 0, -static_cast<int>(indexInfo.minIndex));
+        mDeviceContext->DrawIndexed(count, 0, -minIndex);
     }
 }
 
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
index cc7d40c..75b79f2 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
@@ -1329,20 +1329,22 @@
 {
     startScene();
 
+    int minIndex = static_cast<int>(indexInfo.indexRange.start);
+
     if (mode == GL_POINTS)
     {
-        drawIndexedPoints(count, type, indices, indexInfo.minIndex, elementArrayBuffer);
+        drawIndexedPoints(count, type, indices, minIndex, elementArrayBuffer);
     }
     else if (mode == GL_LINE_LOOP)
     {
-        drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer);
+        drawLineLoop(count, type, indices, minIndex, elementArrayBuffer);
     }
     else
     {
         for (int i = 0; i < mRepeatDraw; i++)
         {
-            GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
-            mDevice->DrawIndexedPrimitive(mPrimitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, mPrimitiveCount);
+            GLsizei vertexCount = static_cast<int>(indexInfo.indexRange.length()) + 1;
+            mDevice->DrawIndexedPrimitive(mPrimitiveType, -minIndex, minIndex, vertexCount, indexInfo.startIndex, mPrimitiveCount);
         }
     }
 }