StateManagerGL: Use dirty bits for VAO bindings.

Delay binding the VAO in VertexArrayGL::syncDrawState until we actually
need to make glVertexAttrib calls.

BUG=angleproject:2188

Change-Id: Ib7d22d641c9f19c639ba8c596bff6bc7de952e7f
Reviewed-on: https://chromium-review.googlesource.com/919503
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Luc Ferron <lucferron@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/gl/StateManagerGL.cpp b/src/libANGLE/renderer/gl/StateManagerGL.cpp
index 256768d..ed835e7 100644
--- a/src/libANGLE/renderer/gl/StateManagerGL.cpp
+++ b/src/libANGLE/renderer/gl/StateManagerGL.cpp
@@ -1037,14 +1037,11 @@
 
 gl::Error StateManagerGL::setGenericDrawState(const gl::Context *context)
 {
-    const gl::State &glState = context->getGLState();
-    const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(glState.getVertexArray());
-    bindVertexArray(vaoGL->getVertexArrayID(), vaoGL->getAppliedElementArrayBufferID());
-
     setGenericShaderState(context);
 
     if (context->getExtensions().webglCompatibility)
     {
+        const gl::State &glState     = context->getGLState();
         FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(glState.getDrawFramebuffer());
         auto activeOutputs = glState.getProgram()->getState().getActiveOutputVariables();
         framebufferGL->maskOutInactiveOutputDrawBuffers(GL_DRAW_FRAMEBUFFER, activeOutputs);
@@ -1053,6 +1050,8 @@
     ASSERT(
         mFramebuffers[angle::FramebufferBindingDraw] ==
         GetImplAs<FramebufferGL>(context->getGLState().getDrawFramebuffer())->getFramebufferID());
+    ASSERT(mVAO ==
+           GetImplAs<VertexArrayGL>(context->getGLState().getVertexArray())->getVertexArrayID());
 
     return gl::NoError();
 }
@@ -1952,10 +1951,14 @@
                 // TODO(jmadill): implement this
                 break;
             case gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING:
-                // TODO(jmadill): implement this
+            {
+                const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(state.getVertexArray());
+                bindVertexArray(vaoGL->getVertexArrayID(), vaoGL->getAppliedElementArrayBufferID());
+
                 propagateNumViewsToVAO(state.getProgram(),
                                        GetImplAs<VertexArrayGL>(state.getVertexArray()));
                 break;
+            }
             case gl::State::DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING:
                 updateDrawIndirectBufferBinding(context);
                 break;
diff --git a/src/libANGLE/renderer/gl/VertexArrayGL.cpp b/src/libANGLE/renderer/gl/VertexArrayGL.cpp
index 25f542f..651ee3e 100644
--- a/src/libANGLE/renderer/gl/VertexArrayGL.cpp
+++ b/src/libANGLE/renderer/gl/VertexArrayGL.cpp
@@ -152,8 +152,6 @@
                                        bool primitiveRestartEnabled,
                                        const void **outIndices) const
 {
-    mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID());
-
     // Check if any attributes need to be streamed, determines if the index range needs to be
     // computed
     bool attributesNeedStreaming = mAttributesNeedStreaming.any();
@@ -233,6 +231,8 @@
             mStreamingElementArrayBufferSize = 0;
         }
 
+        mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID());
+
         mStateManager->bindBuffer(gl::BufferBinding::ElementArray, mStreamingElementArrayBuffer);
         mAppliedElementArrayBuffer.set(context, nullptr);
 
@@ -329,6 +329,8 @@
         mStreamingArrayBufferSize = requiredBufferSize;
     }
 
+    mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID());
+
     // Unmapping a buffer can return GL_FALSE to indicate that the system has corrupted the data
     // somehow (such as by a screen change), retry writing the data a few times and return
     // OUT_OF_MEMORY if that fails.