Optimize Vertex Shader Attribute Type Validition

Improves ValidateVertexShaderAttributeTypeMatch by storing vertex
attributes types into masks for quick comparisons when needed. This shows
2% improvement to glDrawElements for the aquarium workload.

BUG=angleproject:2202

Change-Id: I87fa3d30c3d8cdba6dfd936cd1a41fd27b1c6b77
Reviewed-on: https://chromium-review.googlesource.com/814795
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index 7ccd470..0d223b3 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -991,6 +991,8 @@
 void Program::unlink()
 {
     mState.mAttributes.clear();
+    mState.mAttributesTypeMask.reset();
+    mState.mAttributesMask.reset();
     mState.mActiveAttribLocationsMask.reset();
     mState.mMaxActiveAttribLocation = 0;
     mState.mLinkedTransformFeedbackVaryings.clear();
@@ -2365,6 +2367,9 @@
         }
     }
 
+    ASSERT(mState.mAttributesTypeMask.none());
+    ASSERT(mState.mAttributesMask.none());
+
     for (const sh::Attribute &attribute : mState.mAttributes)
     {
         ASSERT(attribute.location != -1);
@@ -2376,6 +2381,14 @@
             mState.mActiveAttribLocationsMask.set(location);
             mState.mMaxActiveAttribLocation =
                 std::max(mState.mMaxActiveAttribLocation, location + 1);
+
+            // gl_VertexID and gl_InstanceID are active attributes but don't have a bound attribute.
+            if (!attribute.isBuiltIn())
+            {
+                mState.mAttributesTypeMask.setIndex(VariableComponentType(attribute.type),
+                                                    location);
+                mState.mAttributesMask.set(location);
+            }
         }
     }