Use CPU arrays for dynamic indices/vertices on ARM GPUs.
Review URL: https://codereview.appspot.com/7365047

git-svn-id: http://skia.googlecode.com/svn/trunk@7810 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/gpu/gl/GrGLConfig.h b/include/gpu/gl/GrGLConfig.h
index 20d9031..ea24037 100644
--- a/include/gpu/gl/GrGLConfig.h
+++ b/include/gpu/gl/GrGLConfig.h
@@ -96,6 +96,10 @@
  * GR_GL_USE_NV_PATH_RENDERING: Enable experimental support for
  * GL_NV_path_rendering. There are known issues with clipping, non-AA paths, and
  * perspective.
+ *
+ * GR_GL_MUST_USE_VBO: Indicates that all vertices and indices must be rendered
+ * from VBOs. Chromium's command buffer doesn't allow glVertexAttribArray with
+ * ARARY_BUFFER 0 bound or glDrawElements with ELEMENT_ARRAY_BUFFER 0 bound.
  */
 
 #if !defined(GR_GL_LOG_CALLS)
@@ -146,6 +150,10 @@
     #define GR_GL_USE_NV_PATH_RENDERING                 0
 #endif
 
+#if !defined(GR_GL_MUST_USE_VBO)
+    #define GR_GL_MUST_USE_VBO                          0
+#endif
+
 /**
  * There is a strange bug that occurs on Macs with NVIDIA GPUs. We don't
  * fully understand it. When (element) array buffers are continually
diff --git a/include/gpu/gl/GrGLConfig_chrome.h b/include/gpu/gl/GrGLConfig_chrome.h
index 50ea34c..3a74aba 100644
--- a/include/gpu/gl/GrGLConfig_chrome.h
+++ b/include/gpu/gl/GrGLConfig_chrome.h
@@ -34,4 +34,7 @@
 // CheckFramebufferStatus in chrome synchronizes the gpu and renderer processes.
 #define GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT      1
 
+// Non-VBO vertices and indices are not allowed in Chromium.
+#define GR_GL_MUST_USE_VBO                          1
+
 #endif
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index b140a10..bd18e56 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -37,6 +37,7 @@
     fImagingSupport = false;
     fTwoFormatLimit = false;
     fFragCoordsConventionSupport = false;
+    fUseNonVBOVertexAndIndexDynamicData = false;
 }
 
 GrGLCaps::GrGLCaps(const GrGLCaps& caps) {
@@ -67,6 +68,7 @@
     fImagingSupport = caps.fImagingSupport;
     fTwoFormatLimit = caps.fTwoFormatLimit;
     fFragCoordsConventionSupport = caps.fFragCoordsConventionSupport;
+    fUseNonVBOVertexAndIndexDynamicData = caps.fUseNonVBOVertexAndIndexDynamicData;
 
     return *this;
 }
@@ -167,6 +169,11 @@
                                        ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions");
     }
 
+    // Perhaps we should look at the renderer string and limit to Mali GPUs.
+    if (kARM_GrGLVendor == ctxInfo.vendor() && !GR_GL_MUST_USE_VBO) {
+        fUseNonVBOVertexAndIndexDynamicData = true;
+    }
+
     this->initFSAASupport(ctxInfo);
     this->initStencilFormats(ctxInfo);
 }
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 9dfbf23..4143868 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -219,6 +219,11 @@
     /// Is GL_ARB_fragment_coord_conventions supported?
     bool fragCoordConventionsSupport() const { return fFragCoordsConventionSupport; }
 
+    // Use indices or vertices in CPU arrays rather than VBOs for dynamic content.
+    bool useNonVBOVertexAndIndexDynamicData() const {
+        return fUseNonVBOVertexAndIndexDynamicData;
+    }
+
     // Does ReadPixels support the provided format/type combo?
     bool readPixelsSupported(const GrGLInterface* intf,
                              GrGLenum format,
@@ -297,6 +302,7 @@
     bool fImagingSupport  : 1;
     bool fTwoFormatLimit : 1;
     bool fFragCoordsConventionSupport : 1;
+    bool fUseNonVBOVertexAndIndexDynamicData : 1;
 };
 
 #endif
diff --git a/src/gpu/gl/GrGLUtil.cpp b/src/gpu/gl/GrGLUtil.cpp
index 3f110cc..225650c 100644
--- a/src/gpu/gl/GrGLUtil.cpp
+++ b/src/gpu/gl/GrGLUtil.cpp
@@ -171,6 +171,9 @@
         if (0 == strcmp(vendorString, "Intel")) {
             return kIntel_GrGLVendor;
         }
+        if (0 == strcmp(vendorString, "ARM")) {
+            return kARM_GrGLVendor;
+        }
     }
 
     return kOther_GrGLVendor;
diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h
index 997207a..da0c7c3 100644
--- a/src/gpu/gl/GrGLUtil.h
+++ b/src/gpu/gl/GrGLUtil.h
@@ -21,6 +21,7 @@
  */
 enum GrGLVendor {
     kIntel_GrGLVendor,
+    kARM_GrGLVendor,
     kOther_GrGLVendor,
 };
 
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 235811c..b75ab32 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -1231,7 +1231,7 @@
     desc.fSizeInBytes = size;
     desc.fIsWrapped = false;
 
-    if (false && desc.fDynamic) {
+    if (this->glCaps().useNonVBOVertexAndIndexDynamicData() && desc.fDynamic) {
         desc.fID = 0;
         GrGLVertexBuffer* vertexBuffer = SkNEW_ARGS(GrGLVertexBuffer, (this, desc));
         return vertexBuffer;
@@ -1266,7 +1266,7 @@
     desc.fSizeInBytes = size;
     desc.fIsWrapped = false;
 
-    if (false && desc.fDynamic) {
+    if (this->glCaps().useNonVBOVertexAndIndexDynamicData() && desc.fDynamic) {
         desc.fID = 0;
         GrIndexBuffer* indexBuffer = SkNEW_ARGS(GrGLIndexBuffer, (this, desc));
         return indexBuffer;