Only sync attributes used by the current program in RendererGL.

Improves draw call overhead of RendererGL.

DrawCallPerf_gl:
Before: 136973 score
After: 153317 score
Improvement: 11.932%

BUG=angleproject:959

Change-Id: Ib75f6fdd756648e4a07f6e970cda03abbdbcf009
Reviewed-on: https://chromium-review.googlesource.com/275409
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/gl/VertexArrayGL.cpp b/src/libANGLE/renderer/gl/VertexArrayGL.cpp
index c7b6ace..f345ab1 100644
--- a/src/libANGLE/renderer/gl/VertexArrayGL.cpp
+++ b/src/libANGLE/renderer/gl/VertexArrayGL.cpp
@@ -83,22 +83,23 @@
 {
 }
 
-gl::Error VertexArrayGL::syncDrawArraysState(GLint first, GLsizei count) const
+gl::Error VertexArrayGL::syncDrawArraysState(const std::vector<GLuint> &activeAttribLocations, GLint first, GLsizei count) const
 {
-    return syncDrawState(first, count, GL_NONE, nullptr, nullptr);
+    return syncDrawState(activeAttribLocations, first, count, GL_NONE, nullptr, nullptr);
 }
 
-gl::Error VertexArrayGL::syncDrawElementsState(GLsizei count, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const
+gl::Error VertexArrayGL::syncDrawElementsState(const std::vector<GLuint> &activeAttribLocations, GLsizei count,
+                                               GLenum type, const GLvoid *indices, const GLvoid **outIndices) const
 {
-    return syncDrawState(0, count, type, indices, outIndices);
+    return syncDrawState(activeAttribLocations, 0, count, type, indices, outIndices);
 }
 
-gl::Error VertexArrayGL::syncDrawState(GLint first, GLsizei count, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const
+gl::Error VertexArrayGL::syncDrawState(const std::vector<GLuint> &activeAttribLocations, GLint first, GLsizei count, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const
 {
     mStateManager->bindVertexArray(mVertexArrayID, mAppliedElementArrayBuffer);
 
     // Check if any attributes need to be streamed, determines if the index range needs to be computed
-    bool attributesNeedStreaming = doAttributesNeedStreaming();
+    bool attributesNeedStreaming = doAttributesNeedStreaming(activeAttribLocations);
 
     // Determine if an index buffer needs to be streamed and the range of vertices that need to be copied
     gl::RangeUI indexRange(0, 0);
@@ -120,7 +121,8 @@
     // Sync the vertex attribute state and track what data needs to be streamed
     size_t streamingDataSize = 0;
     size_t maxAttributeDataSize = 0;
-    gl::Error error = syncAttributeState(attributesNeedStreaming, indexRange, &streamingDataSize, &maxAttributeDataSize);
+    gl::Error error = syncAttributeState(activeAttribLocations, attributesNeedStreaming, indexRange,
+                                         &streamingDataSize, &maxAttributeDataSize);
     if (error.isError())
     {
         return error;
@@ -130,7 +132,8 @@
     {
         ASSERT(attributesNeedStreaming);
 
-        gl::Error error = streamAttributes(streamingDataSize, maxAttributeDataSize, indexRange);
+        gl::Error error = streamAttributes(activeAttribLocations, streamingDataSize, maxAttributeDataSize,
+                                           indexRange);
         if (error.isError())
         {
             return error;
@@ -140,12 +143,13 @@
     return gl::Error(GL_NO_ERROR);
 }
 
-bool VertexArrayGL::doAttributesNeedStreaming() const
+bool VertexArrayGL::doAttributesNeedStreaming(const std::vector<GLuint> &activeAttribLocations) const
 {
     // TODO: if GLES, nothing needs to be streamed
     const auto &attribs = mData.getVertexAttributes();
-    for (size_t idx = 0; idx < attribs.size(); idx++)
+    for (size_t activeAttrib = 0; activeAttrib < activeAttribLocations.size(); activeAttrib++)
     {
+        GLuint idx = activeAttribLocations[activeAttrib];
         if (attribs[idx].enabled && attribs[idx].buffer.get() == nullptr)
         {
             return true;
@@ -155,15 +159,16 @@
     return false;
 }
 
-gl::Error VertexArrayGL::syncAttributeState(bool attributesNeedStreaming, const gl::RangeUI &indexRange,
-                                            size_t *outStreamingDataSize, size_t *outMaxAttributeDataSize) const
+gl::Error VertexArrayGL::syncAttributeState(const std::vector<GLuint> &activeAttribLocations, bool attributesNeedStreaming,
+                                            const gl::RangeUI &indexRange,  size_t *outStreamingDataSize, size_t *outMaxAttributeDataSize) const
 {
     *outStreamingDataSize = 0;
     *outMaxAttributeDataSize = 0;
 
     const auto &attribs = mData.getVertexAttributes();
-    for (size_t idx = 0; idx < attribs.size(); idx++)
+    for (size_t activeAttrib = 0; activeAttrib < activeAttribLocations.size(); activeAttrib++)
     {
+        GLuint idx = activeAttribLocations[activeAttrib];
         const auto &attrib = attribs[idx];
 
         // Always sync the enabled and divisor state, they are required for both streaming and buffered
@@ -310,7 +315,8 @@
     return gl::Error(GL_NO_ERROR);
 }
 
-gl::Error VertexArrayGL::streamAttributes(size_t streamingDataSize, size_t maxAttributeDataSize, const gl::RangeUI &indexRange) const
+gl::Error VertexArrayGL::streamAttributes(const std::vector<GLuint> &activeAttribLocations, size_t streamingDataSize,
+                                          size_t maxAttributeDataSize, const gl::RangeUI &indexRange) const
 {
     if (mStreamingArrayBuffer == 0)
     {
@@ -343,8 +349,9 @@
         const size_t streamedVertexCount = indexRange.end - indexRange.start + 1;
 
         const auto &attribs = mData.getVertexAttributes();
-        for (size_t idx = 0; idx < attribs.size(); idx++)
+        for (size_t activeAttrib = 0; activeAttrib < activeAttribLocations.size(); activeAttrib++)
         {
+            GLuint idx = activeAttribLocations[activeAttrib];
             const auto &attrib = attribs[idx];
 
             if (attrib.enabled && attrib.buffer.get() == nullptr)