Move client attribs mask to front-end.

The Vulkan and GL back-ends both had a client attributes mask.
This consolidates them into the front-end, where it can also
be used in the validation layer.

Also includes a fix which was incorrectly setting the enabled
mask in setVertexAttribFormatImpl.

Bug: angleproject:1391
Change-Id: I5e45c1e2a56b30a36dec1482d170592c30a16d40
Reviewed-on: https://chromium-review.googlesource.com/1008272
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Luc Ferron <lucferron@chromium.org>
diff --git a/src/libANGLE/renderer/gl/VertexArrayGL.cpp b/src/libANGLE/renderer/gl/VertexArrayGL.cpp
index cac5912..c8c0370 100644
--- a/src/libANGLE/renderer/gl/VertexArrayGL.cpp
+++ b/src/libANGLE/renderer/gl/VertexArrayGL.cpp
@@ -26,12 +26,6 @@
 {
 namespace
 {
-// Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
-bool AttributeNeedsStreaming(const VertexAttribute &attrib, const VertexBinding &binding)
-{
-    return (attrib.enabled && binding.getBuffer().get() == nullptr);
-}
-
 bool SameVertexAttribFormat(const VertexAttribute &a, const VertexAttribute &b)
 {
     return a.size == b.size && a.type == b.type && a.normalized == b.normalized &&
@@ -154,7 +148,8 @@
 {
     // Check if any attributes need to be streamed, determines if the index range needs to be
     // computed
-    bool attributesNeedStreaming = mAttributesNeedStreaming.any();
+    const gl::AttributesMask &needsStreamingAttribs =
+        (mState.getEnabledClientMemoryAttribsMask() & activeAttributesMask);
 
     // Determine if an index buffer needs to be streamed and the range of vertices that need to be
     // copied
@@ -162,7 +157,7 @@
     if (type != GL_NONE)
     {
         ANGLE_TRY(syncIndexData(context, count, type, indices, primitiveRestartEnabled,
-                                attributesNeedStreaming, &indexRange, outIndices));
+                                needsStreamingAttribs.any(), &indexRange, outIndices));
     }
     else
     {
@@ -171,9 +166,9 @@
         indexRange.end   = first + count - 1;
     }
 
-    if (attributesNeedStreaming)
+    if (needsStreamingAttribs.any())
     {
-        ANGLE_TRY(streamAttributes(activeAttributesMask, instanceCount, indexRange));
+        ANGLE_TRY(streamAttributes(needsStreamingAttribs, instanceCount, indexRange));
     }
 
     return gl::NoError();
@@ -261,7 +256,7 @@
     return gl::NoError();
 }
 
-void VertexArrayGL::computeStreamingAttributeSizes(const gl::AttributesMask &activeAttributesMask,
+void VertexArrayGL::computeStreamingAttributeSizes(const gl::AttributesMask &attribsToStream,
                                                    GLsizei instanceCount,
                                                    const gl::IndexRange &indexRange,
                                                    size_t *outStreamingDataSize,
@@ -270,18 +265,15 @@
     *outStreamingDataSize    = 0;
     *outMaxAttributeDataSize = 0;
 
-    ASSERT(mAttributesNeedStreaming.any());
+    ASSERT(attribsToStream.any());
 
     const auto &attribs  = mState.getVertexAttributes();
     const auto &bindings = mState.getVertexBindings();
 
-    gl::AttributesMask attribsToStream = (mAttributesNeedStreaming & activeAttributesMask);
-
     for (auto idx : attribsToStream)
     {
         const auto &attrib  = attribs[idx];
         const auto &binding = bindings[attrib.bindingIndex];
-        ASSERT(AttributeNeedsStreaming(attrib, binding));
 
         // If streaming is going to be required, compute the size of the required buffer
         // and how much slack space at the beginning of the buffer will be required by determining
@@ -295,7 +287,7 @@
     }
 }
 
-gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttributesMask,
+gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &attribsToStream,
                                           GLsizei instanceCount,
                                           const gl::IndexRange &indexRange) const
 {
@@ -303,8 +295,8 @@
     size_t streamingDataSize    = 0;
     size_t maxAttributeDataSize = 0;
 
-    computeStreamingAttributeSizes(activeAttributesMask, instanceCount, indexRange,
-                                   &streamingDataSize, &maxAttributeDataSize);
+    computeStreamingAttributeSizes(attribsToStream, instanceCount, indexRange, &streamingDataSize,
+                                   &maxAttributeDataSize);
 
     if (streamingDataSize == 0)
     {
@@ -345,15 +337,12 @@
         const auto &attribs  = mState.getVertexAttributes();
         const auto &bindings = mState.getVertexBindings();
 
-        gl::AttributesMask attribsToStream = (mAttributesNeedStreaming & activeAttributesMask);
-
         for (auto idx : attribsToStream)
         {
             const auto &attrib  = attribs[idx];
             ASSERT(IsVertexAttribPointerSupported(idx, attrib));
 
             const auto &binding = bindings[attrib.bindingIndex];
-            ASSERT(AttributeNeedsStreaming(attrib, binding));
 
             GLuint adjustedDivisor = GetAdjustedDivisor(mAppliedNumViews, binding.getDivisor());
             const size_t streamedVertexCount = ComputeVertexBindingElementCount(
@@ -425,13 +414,6 @@
     return GetImplAs<BufferGL>(mAppliedElementArrayBuffer.get())->getBufferID();
 }
 
-void VertexArrayGL::updateNeedsStreaming(size_t attribIndex)
-{
-    const auto &attrib  = mState.getVertexAttribute(attribIndex);
-    const auto &binding = mState.getBindingFromAttribIndex(attribIndex);
-    mAttributesNeedStreaming.set(attribIndex, AttributeNeedsStreaming(attrib, binding));
-}
-
 void VertexArrayGL::updateAttribEnabled(size_t attribIndex)
 {
     const bool enabled = mState.getVertexAttribute(attribIndex).enabled;
@@ -440,8 +422,6 @@
         return;
     }
 
-    updateNeedsStreaming(attribIndex);
-
     if (enabled)
     {
         mFunctions->enableVertexAttribArray(static_cast<GLuint>(attribIndex));
@@ -462,21 +442,12 @@
     // of the binding indexed attrib.bindingIndex (unless attribIndex == attrib.bindingIndex).
     const VertexBinding &binding = mState.getVertexBinding(attribIndex);
 
-    // Since mAttributesNeedStreaming[attribIndex] keeps the value set in the last draw, here we
-    // only need to update it when the buffer has been changed. e.g. When we set an attribute to be
-    // streamed in the last draw, and only change its format in this draw without calling
-    // updateNeedsStreaming, it will still be streamed because the flag is already on.
-    const auto &bindingBuffer = binding.getBuffer();
-    if (bindingBuffer != mAppliedBindings[attribIndex].getBuffer())
-    {
-        updateNeedsStreaming(attribIndex);
-    }
-
     // Early return when the vertex attribute isn't using a buffer object:
     // - If we need to stream, defer the attribPointer to the draw call.
     // - Skip the attribute that is disabled and uses a client memory pointer.
     // - Skip the attribute whose buffer is detached by BindVertexBuffer. Since it cannot have a
     //   client memory pointer either, it must be disabled and shouldn't affect the draw.
+    const auto &bindingBuffer = binding.getBuffer();
     const Buffer *arrayBuffer = bindingBuffer.get();
     if (arrayBuffer == nullptr)
     {