Refactor how Gr handles vertex and index data. GrGpu and GrInOrderDrawBuffer both GrBufferAllocPool to manage reserved and set-to-array vertex and index data.

rietveld issue 4188049

git-svn-id: http://skia.googlecode.com/svn/trunk@786 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrGpuGLShaders2.cpp b/gpu/src/GrGpuGLShaders2.cpp
index 81f83c9..d423ee2 100644
--- a/gpu/src/GrGpuGLShaders2.cpp
+++ b/gpu/src/GrGpuGLShaders2.cpp
@@ -983,7 +983,7 @@
 
     // Must initialize all fields or cache will have false negatives!
     desc->fVertexLayout = fGeometrySrc.fVertexLayout;
-    
+
     desc->fOptFlags = 0;
     if (kPoints_PrimitiveType != primType) {
         desc->fOptFlags |= ProgramDesc::kNotPoints_OptFlagBit;
@@ -1112,7 +1112,7 @@
     fTextureOrientation = (GrGLTexture::Orientation)-1; // illegal
 
     fHWGeometryState.fVertexLayout = 0;
-    fHWGeometryState.fPositionPtr  = (void*) ~0;
+    fHWGeometryState.fVertexOffset  = ~0;
     GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION));
     for (int t = 0; t < kMaxTexCoords; ++t) {
         GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION(t)));
@@ -1315,10 +1315,10 @@
     return true;
 }
 
-void GrGpuGLShaders2::setupGeometry(uint32_t startVertex,
-                                    uint32_t startIndex,
-                                    uint32_t vertexCount,
-                                    uint32_t indexCount) {
+void GrGpuGLShaders2::setupGeometry(int* startVertex,
+                                    int* startIndex,
+                                    int vertexCount,
+                                    int indexCount) {
 
     int newColorOffset;
     int newTexCoordOffsets[kMaxTexCoords];
@@ -1331,10 +1331,11 @@
     GLsizei oldStride = VertexSizeAndOffsetsByIdx(fHWGeometryState.fVertexLayout,
                                                   oldTexCoordOffsets,
                                                   &oldColorOffset);
+    bool indexed = NULL != startIndex;
 
-    const GLvoid* posPtr = setBuffersAndGetVertexStart(newStride, startVertex, 
-                                                       startIndex, vertexCount,
-                                                       indexCount);
+    int extraVertexOffset;
+    int extraIndexOffset;
+    setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
 
     GLenum scalarType;
     bool texCoordNorm;
@@ -1346,31 +1347,42 @@
         texCoordNorm = false;
     }
 
-    bool baseChange = posPtr != fHWGeometryState.fPositionPtr;
-    bool scalarChange = (GrGLTextType != GrGLType) &&
-                        (kTextFormat_VertexLayoutBit &
-                         (fHWGeometryState.fVertexLayout ^
-                          fGeometrySrc.fVertexLayout));
-    bool strideChange = newStride != oldStride;
-    bool posChange = baseChange || scalarChange || strideChange;
+    size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride;
+    *startVertex = 0;
+    if (indexed) {
+        *startIndex += extraIndexOffset;
+    }
 
-    if (fHWGeometryState.fArrayPtrsDirty || posChange) {
+    // all the Pointers must be set if any of these are true
+    bool allOffsetsChange =  fHWGeometryState.fArrayPtrsDirty ||
+                             vertexOffset != fHWGeometryState.fVertexOffset ||
+                             newStride != oldStride;
+
+    // position and tex coord offsets change if above conditions are true
+    // or the type/normalization changed based on text vs nontext type coords.
+    bool posAndTexChange = allOffsetsChange ||
+                           (((GrGLTextType != GrGLType) || GR_GL_TEXT_TEXTURE_NORMALIZED) &&
+                                (kTextFormat_VertexLayoutBit &
+                                  (fHWGeometryState.fVertexLayout ^
+                                   fGeometrySrc.fVertexLayout)));
+
+    if (posAndTexChange) {
         GR_GL(VertexAttribPointer(POS_ATTR_LOCATION, 2, scalarType,
-                                  false, newStride, posPtr));
-        fHWGeometryState.fPositionPtr = posPtr;
+                                  false, newStride, (GLvoid*)vertexOffset));
+        fHWGeometryState.fVertexOffset = vertexOffset;
     }
 
     for (int t = 0; t < kMaxTexCoords; ++t) {
         if (newTexCoordOffsets[t] > 0) {
-            GLvoid* texCoordPtr = (int8_t*)posPtr + newTexCoordOffsets[t];
+            GLvoid* texCoordOffset = (GLvoid*)(vertexOffset + newTexCoordOffsets[t]);
             if (oldTexCoordOffsets[t] <= 0) {
                 GR_GL(EnableVertexAttribArray(TEX_ATTR_LOCATION(t)));
                 GR_GL(VertexAttribPointer(TEX_ATTR_LOCATION(t), 2, scalarType,
-                                          texCoordNorm, newStride, texCoordPtr));
-            } else if (fHWGeometryState.fArrayPtrsDirty || posChange || 
-                newTexCoordOffsets[t] != oldTexCoordOffsets[t]) {
+                                          texCoordNorm, newStride, texCoordOffset));
+            } else if (posAndTexChange ||
+                       newTexCoordOffsets[t] != oldTexCoordOffsets[t]) {
                 GR_GL(VertexAttribPointer(TEX_ATTR_LOCATION(t), 2, scalarType,
-                                          texCoordNorm, newStride, texCoordPtr));
+                                          texCoordNorm, newStride, texCoordOffset));
             }
         } else if (oldTexCoordOffsets[t] > 0) {
             GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION(t)));
@@ -1378,23 +1390,23 @@
     }
 
     if (newColorOffset > 0) {
-        GLvoid* colorPtr = (int8_t*)posPtr + newColorOffset;
+        GLvoid* colorOffset = (int8_t*)(vertexOffset + newColorOffset);
         if (oldColorOffset <= 0) {
             GR_GL(EnableVertexAttribArray(COL_ATTR_LOCATION));
             GR_GL(VertexAttribPointer(COL_ATTR_LOCATION, 4,
                                       GL_UNSIGNED_BYTE,
-                                      true, newStride, colorPtr));
-        } else if (fHWGeometryState.fArrayPtrsDirty || posChange || 
-            newColorOffset != oldColorOffset) {
+                                      true, newStride, colorOffset));
+        } else if (allOffsetsChange || newColorOffset != oldColorOffset) {
             GR_GL(VertexAttribPointer(COL_ATTR_LOCATION, 4,
                                       GL_UNSIGNED_BYTE,
-                                      true, newStride, colorPtr));
+                                      true, newStride, colorOffset));
         }
     } else if (oldColorOffset > 0) {
         GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION));
     }
 
     fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
+    fHWGeometryState.fArrayPtrsDirty = false;
 }
 #endif