Implement dirty bits acceleration for Current Values.

BUG=angleproject:1040
TEST=angle_end2end_tests,angle_perftests,WebGL

Change-Id: If471cfb9676795d5cc985eea52ad7144d4544ed1
Reviewed-on: https://chromium-review.googlesource.com/289559
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index 3e8ec36..8e8330c 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -1057,18 +1057,21 @@
 {
     ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
     mVertexAttribCurrentValues[index].setFloatValues(values);
+    mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
 }
 
 void State::setVertexAttribu(GLuint index, const GLuint values[4])
 {
     ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
     mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
+    mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
 }
 
 void State::setVertexAttribi(GLuint index, const GLint values[4])
 {
     ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
     mVertexAttribCurrentValues[index].setIntValues(values);
+    mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
 }
 
 void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
diff --git a/src/libANGLE/State.h b/src/libANGLE/State.h
index dad3b6e..a7c4afe 100644
--- a/src/libANGLE/State.h
+++ b/src/libANGLE/State.h
@@ -306,8 +306,10 @@
         DIRTY_BIT_VERTEX_ARRAY_OBJECT,
         DIRTY_BIT_PROGRAM_BINDING,
         DIRTY_BIT_PROGRAM_OBJECT,
-        DIRTY_BIT_INVALID,
-        DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
+        DIRTY_BIT_CURRENT_VALUE_0,
+        DIRTY_BIT_CURRENT_VALUE_MAX = DIRTY_BIT_CURRENT_VALUE_0 + MAX_VERTEX_ATTRIBS,
+        DIRTY_BIT_INVALID           = DIRTY_BIT_CURRENT_VALUE_MAX,
+        DIRTY_BIT_MAX               = DIRTY_BIT_INVALID,
     };
 
     typedef std::bitset<DIRTY_BIT_MAX> DirtyBits;
diff --git a/src/libANGLE/renderer/gl/StateManagerGL.cpp b/src/libANGLE/renderer/gl/StateManagerGL.cpp
index 87307cd..99465ad 100644
--- a/src/libANGLE/renderer/gl/StateManagerGL.cpp
+++ b/src/libANGLE/renderer/gl/StateManagerGL.cpp
@@ -424,19 +424,6 @@
     const ProgramGL *programGL = GetImplAs<ProgramGL>(program);
     useProgram(programGL->getProgramID());
 
-    const gl::VertexArray *vao = state.getVertexArray();
-    const std::vector<gl::VertexAttribute> &attribs = vao->getVertexAttributes();
-    const std::vector<GLuint> &activeAttribs = programGL->getActiveAttributeLocations();
-
-    for (size_t activeAttribIndex = 0; activeAttribIndex < activeAttribs.size(); activeAttribIndex++)
-    {
-        GLuint location = activeAttribs[activeAttribIndex];
-        if (!attribs[location].enabled)
-        {
-            setAttributeCurrentData(location, state.getVertexAttribCurrentValue(location));
-        }
-    }
-
     const std::vector<SamplerBindingGL> &appliedSamplerUniforms = programGL->getAppliedSamplerUniforms();
     for (const SamplerBindingGL &samplerUniform : appliedSamplerUniforms)
     {
@@ -899,6 +886,7 @@
 
 void StateManagerGL::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits)
 {
+    // TODO(jmadill): Investigate only syncing vertex state for active attributes
     for (unsigned int dirtyBit : angle::IterateBitSet(dirtyBits))
     {
         switch (dirtyBit)
@@ -1091,8 +1079,15 @@
                 // TODO(jmadill): implement this
                 break;
             default:
-                UNREACHABLE();
+            {
+                ASSERT(dirtyBit >= gl::State::DIRTY_BIT_CURRENT_VALUE_0 &&
+                       dirtyBit < gl::State::DIRTY_BIT_CURRENT_VALUE_MAX);
+                size_t attribIndex =
+                    static_cast<size_t>(dirtyBit) - gl::State::DIRTY_BIT_CURRENT_VALUE_0;
+                setAttributeCurrentData(attribIndex, state.getVertexAttribCurrentValue(
+                                                         static_cast<unsigned int>(attribIndex)));
                 break;
+            }
         }
     }
 }