Introduce SubjectBindingPointer.

We can share the same pointer for the subject binding and the binding
pointer. This further allows us to optimize buffer re-binding. The
shared memory increases cache coherency and reduces the number of
instructions needed.

Bug: angleproject:2891
Change-Id: Id3162fa79de203f75989e7289ea02cb2ea1bec73
Reviewed-on: https://chromium-review.googlesource.com/c/1270217
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
diff --git a/src/libANGLE/VertexArray.cpp b/src/libANGLE/VertexArray.cpp
index b8c232c..a9a8be8 100644
--- a/src/libANGLE/VertexArray.cpp
+++ b/src/libANGLE/VertexArray.cpp
@@ -21,11 +21,15 @@
 {
     return (subjectIndex == MAX_VERTEX_ATTRIBS);
 }
+
+constexpr angle::SubjectIndex kElementArrayBufferIndex = MAX_VERTEX_ATTRIBS;
 }  // anonymous namespce
 
 // VertexArrayState implementation.
-VertexArrayState::VertexArrayState(size_t maxAttribs, size_t maxAttribBindings)
-    : mLabel(), mVertexBindings()
+VertexArrayState::VertexArrayState(VertexArray *vertexArray,
+                                   size_t maxAttribs,
+                                   size_t maxAttribBindings)
+    : mElementArrayBuffer(vertexArray, kElementArrayBufferIndex)
 {
     ASSERT(maxAttribs <= maxAttribBindings);
 
@@ -89,9 +93,8 @@
                          size_t maxAttribs,
                          size_t maxAttribBindings)
     : mId(id),
-      mState(maxAttribs, maxAttribBindings),
-      mVertexArray(factory->createVertexArray(mState)),
-      mElementArrayBufferObserverBinding(this, MAX_VERTEX_ATTRIBS)
+      mState(this, maxAttribs, maxAttribBindings),
+      mVertexArray(factory->createVertexArray(mState))
 {
     for (size_t attribIndex = 0; attribIndex < maxAttribBindings; ++attribIndex)
     {
@@ -108,7 +111,7 @@
     }
     if (isBound && mState.mElementArrayBuffer.get())
         mState.mElementArrayBuffer->onNonTFBindingChanged(-1);
-    mState.mElementArrayBuffer.set(context, nullptr);
+    mState.mElementArrayBuffer.bind(context, nullptr);
     mVertexArray->destroy(context);
     SafeDelete(mVertexArray);
     delete this;
@@ -145,11 +148,11 @@
         }
     }
 
-    if (mState.mElementArrayBuffer.id() == bufferName)
+    if (mState.mElementArrayBuffer.get() && mState.mElementArrayBuffer->id() == bufferName)
     {
         if (isBound && mState.mElementArrayBuffer.get())
             mState.mElementArrayBuffer->onNonTFBindingChanged(-1);
-        mState.mElementArrayBuffer.set(context, nullptr);
+        mState.mElementArrayBuffer.bind(context, nullptr);
     }
 }