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/GrGLVertexBuffer.cpp b/gpu/src/GrGLVertexBuffer.cpp
index b4ddc24..ec48936 100644
--- a/gpu/src/GrGLVertexBuffer.cpp
+++ b/gpu/src/GrGLVertexBuffer.cpp
@@ -18,8 +18,8 @@
 #include "GrGLVertexBuffer.h"
 #include "GrGpuGL.h"
 
-GrGLVertexBuffer::GrGLVertexBuffer(GLuint id, GrGpuGL* gl, uint32_t sizeInBytes,
-                                   bool dynamic) : 
+GrGLVertexBuffer::GrGLVertexBuffer(GLuint id, GrGpuGL* gl, size_t sizeInBytes,
+                                   bool dynamic) :
                                    INHERITED(sizeInBytes, dynamic),
                                    fGL(gl),
                                    fBufferID(id),
@@ -34,11 +34,16 @@
     }
 }
 
+void GrGLVertexBuffer::bind() const {
+    GR_GL(BindBuffer(GL_ARRAY_BUFFER, fBufferID));
+    fGL->notifyVertexBufferBind(this);
+}
+
 GLuint GrGLVertexBuffer::bufferID() const {
     return fBufferID;
 }
 
-void GrGLVertexBuffer::abandon() { 
+void GrGLVertexBuffer::abandon() {
     fBufferID = 0;
     fGL = NULL;
     fLockPtr = NULL;
@@ -48,30 +53,29 @@
     GrAssert(fBufferID);
     GrAssert(!isLocked());
     if (fGL->supportsBufferLocking()) {
-        GR_GL(BindBuffer(GL_ARRAY_BUFFER, fBufferID));
-        fGL->notifyVertexBufferBind(this);
-        // call bufferData with null ptr to allow driver to perform renaming
-        // If this call is removed revisit updateData to be sure it doesn't
-        // leave buffer undersized (as it currently does).
-        GR_GL(BufferData(GL_ARRAY_BUFFER, size(), NULL, 
+        bind();
+        // Let driver know it can discard the old data
+        GR_GL(BufferData(GL_ARRAY_BUFFER, size(), NULL,
                          dynamic() ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW));
         fLockPtr = GR_GLEXT(fGL->extensions(),
-                            MapBuffer(GL_ARRAY_BUFFER, GR_WRITE_ONLY)); 
+                            MapBuffer(GL_ARRAY_BUFFER, GR_WRITE_ONLY));
         return fLockPtr;
     }
     return NULL;
 }
 
+void* GrGLVertexBuffer::lockPtr() const {
+    return fLockPtr;
+}
+
 void GrGLVertexBuffer::unlock() {
     GrAssert(fBufferID);
     GrAssert(isLocked());
-    if (fGL->supportsBufferLocking()) {
-        GR_GL(BindBuffer(GL_ARRAY_BUFFER, fBufferID));
-        fGL->notifyVertexBufferBind(this);
-        GR_GLEXT(fGL->extensions(),
-                 UnmapBuffer(GL_ARRAY_BUFFER));
-        fLockPtr = NULL;
-    }
+    GrAssert(fGL->supportsBufferLocking());
+
+    bind();
+    GR_GLEXT(fGL->extensions(), UnmapBuffer(GL_ARRAY_BUFFER));
+    fLockPtr = NULL;
 }
 
 bool GrGLVertexBuffer::isLocked() const {
@@ -79,8 +83,7 @@
 #if GR_DEBUG
     if (fGL->supportsBufferLocking()) {
         GLint mapped;
-        GR_GL(BindBuffer(GL_ARRAY_BUFFER, fBufferID));
-        fGL->notifyVertexBufferBind(this);
+        bind();
         GR_GL(GetBufferParameteriv(GL_ARRAY_BUFFER, GR_BUFFER_MAPPED, &mapped));
         GrAssert(!!mapped == !!fLockPtr);
     }
@@ -88,16 +91,33 @@
     return NULL != fLockPtr;
 }
 
-bool GrGLVertexBuffer::updateData(const void* src, uint32_t srcSizeInBytes) {
+bool GrGLVertexBuffer::updateData(const void* src, size_t srcSizeInBytes) {
     GrAssert(fBufferID);
     GrAssert(!isLocked());
     if (srcSizeInBytes > size()) {
         return false;
     }
-    GR_GL(BindBuffer(GL_ARRAY_BUFFER, fBufferID));
-    fGL->notifyVertexBufferBind(this);
-    GR_GL(BufferData(GL_ARRAY_BUFFER, srcSizeInBytes, src, 
-                     dynamic() ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW));
+    bind();
+    GLenum usage = dynamic() ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
+    if (size() == srcSizeInBytes) {
+        GR_GL(BufferData(GL_ARRAY_BUFFER, srcSizeInBytes, src, usage));
+    } else {
+        GR_GL(BufferData(GL_ARRAY_BUFFER, size(), NULL, usage));
+        GR_GL(BufferSubData(GL_ARRAY_BUFFER, 0, srcSizeInBytes, src));
+    }
+    return true;
+}
+
+bool GrGLVertexBuffer::updateSubData(const void* src,
+                                     size_t srcSizeInBytes,
+                                     size_t offset) {
+    GrAssert(fBufferID);
+    GrAssert(!isLocked());
+    if (srcSizeInBytes + offset > size()) {
+        return false;
+    }
+    bind();
+    GR_GL(BufferSubData(GL_ARRAY_BUFFER, offset, srcSizeInBytes, src));
     return true;
 }