Add Context::getActiveBufferedAttribsMask.

This will enable more caching for ValidateDrawAttribs. It requires some
minor refactoring of the GLES 1 code.

Bug: angleproject:1391
Change-Id: I52b73c9384d14cdb90ba6337bfc1ab345866fff0
Reviewed-on: https://chromium-review.googlesource.com/1147436
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 1bdd2bb..15c44e8 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -7531,6 +7531,28 @@
     mGLState.setMaxShaderCompilerThreads(count);
 }
 
+bool Context::isGLES1() const
+{
+    return mState.getClientVersion() < Version(2, 0);
+}
+
+AttributesMask Context::getActiveBufferedAttribsMask() const
+{
+    // TODO(jmadill): Cache this. http://anglebug.com/1391
+    ASSERT(mGLState.getProgram() || isGLES1());
+
+    const AttributesMask &activeAttribs =
+        isGLES1() ? mGLState.gles1().getVertexArraysAttributeMask()
+                  : mGLState.getProgram()->getActiveAttribLocationsMask();
+
+    const VertexArray *vao = mGLState.getVertexArray();
+    ASSERT(vao);
+
+    const AttributesMask &clientAttribs = vao->getEnabledClientMemoryAttribsMask();
+
+    return (activeAttribs & vao->getEnabledAttributesMask() & ~clientAttribs);
+}
+
 // ErrorSet implementation.
 ErrorSet::ErrorSet(Context *context) : mContext(context)
 {
diff --git a/src/libANGLE/Context.h b/src/libANGLE/Context.h
index e118527..8da1df9 100644
--- a/src/libANGLE/Context.h
+++ b/src/libANGLE/Context.h
@@ -1458,6 +1458,7 @@
     const Extensions &getExtensions() const { return mState.getExtensions(); }
     const Limitations &getLimitations() const { return mState.getLimitations(); }
     bool skipValidation() const { return mSkipValidation; }
+    bool isGLES1() const;
 
     // Specific methods needed for validation.
     bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
@@ -1488,11 +1489,12 @@
     // GLES1 emulation: Renderer level (for validation)
     int vertexArrayIndex(ClientVertexArrayType type) const;
     static int TexCoordArrayIndex(unsigned int unit);
-    AttributesMask getVertexArraysAttributeMask() const;
 
     // GL_KHR_parallel_shader_compile
     void maxShaderCompilerThreads(GLuint count);
 
+    AttributesMask getActiveBufferedAttribsMask() const;
+
   private:
     void initialize();
 
diff --git a/src/libANGLE/Context_gles_1_0.cpp b/src/libANGLE/Context_gles_1_0.cpp
index fdf14c1..68f0d70 100644
--- a/src/libANGLE/Context_gles_1_0.cpp
+++ b/src/libANGLE/Context_gles_1_0.cpp
@@ -709,7 +709,7 @@
 
 int Context::vertexArrayIndex(ClientVertexArrayType type) const
 {
-    return mGLES1Renderer->vertexArrayIndex(type, &mGLState);
+    return GLES1Renderer::VertexArrayIndex(type, mGLState.gles1());
 }
 
 // static
@@ -717,11 +717,4 @@
 {
     return GLES1Renderer::TexCoordArrayIndex(unit);
 }
-
-AttributesMask Context::getVertexArraysAttributeMask() const
-{
-    return mGLES1Renderer->getVertexArraysAttributeMask(&mGLState);
-}
-
-// static
 }  // namespace gl
diff --git a/src/libANGLE/GLES1Renderer.cpp b/src/libANGLE/GLES1Renderer.cpp
index b1cb323..75da6c5 100644
--- a/src/libANGLE/GLES1Renderer.cpp
+++ b/src/libANGLE/GLES1Renderer.cpp
@@ -397,7 +397,8 @@
     return NoError();
 }
 
-int GLES1Renderer::vertexArrayIndex(ClientVertexArrayType type, const State *glState) const
+// static
+int GLES1Renderer::VertexArrayIndex(ClientVertexArrayType type, const GLES1State &gles1)
 {
     switch (type)
     {
@@ -410,7 +411,7 @@
         case ClientVertexArrayType::PointSize:
             return kPointSizeAttribIndex;
         case ClientVertexArrayType::TextureCoord:
-            return kTextureCoordAttribIndexBase + glState->gles1().getClientTextureUnit();
+            return kTextureCoordAttribIndexBase + gles1.getClientTextureUnit();
         default:
             UNREACHABLE();
             return 0;
@@ -423,29 +424,6 @@
     return kTextureCoordAttribIndexBase + unit;
 }
 
-AttributesMask GLES1Renderer::getVertexArraysAttributeMask(const State *glState) const
-{
-    AttributesMask res;
-    const GLES1State &gles1 = glState->gles1();
-
-    ClientVertexArrayType nonTexcoordArrays[] = {
-        ClientVertexArrayType::Vertex, ClientVertexArrayType::Normal, ClientVertexArrayType::Color,
-        ClientVertexArrayType::PointSize,
-    };
-
-    for (const ClientVertexArrayType attrib : nonTexcoordArrays)
-    {
-        res.set(vertexArrayIndex(attrib, glState), gles1.isClientStateEnabled(attrib));
-    }
-
-    for (unsigned int i = 0; i < kTexUnitCount; i++)
-    {
-        res.set(TexCoordArrayIndex(i), gles1.isTexCoordArrayEnabled(i));
-    }
-
-    return res;
-}
-
 void GLES1Renderer::drawTexture(Context *context,
                                 State *glState,
                                 float x,
@@ -476,7 +454,7 @@
 
     mDrawTextureEnabled = true;
 
-    AttributesMask prevAttributesMask = getVertexArraysAttributeMask(glState);
+    AttributesMask prevAttributesMask = glState->gles1().getVertexArraysAttributeMask();
 
     setAttributesEnabled(context, glState, AttributesMask());
 
@@ -832,7 +810,7 @@
 
     for (const ClientVertexArrayType attrib : nonTexcoordArrays)
     {
-        int index = vertexArrayIndex(attrib, glState);
+        int index = VertexArrayIndex(attrib, glState->gles1());
 
         if (mask.test(index))
         {
diff --git a/src/libANGLE/GLES1Renderer.h b/src/libANGLE/GLES1Renderer.h
index 86fe8c4..875de2e 100644
--- a/src/libANGLE/GLES1Renderer.h
+++ b/src/libANGLE/GLES1Renderer.h
@@ -20,8 +20,8 @@
 
 namespace gl
 {
-
 class Context;
+class GLES1State;
 class Program;
 class State;
 class Shader;
@@ -37,9 +37,8 @@
 
     Error prepareForDraw(PrimitiveMode mode, Context *context, State *glState);
 
-    int vertexArrayIndex(ClientVertexArrayType type, const State *glState) const;
+    static int VertexArrayIndex(ClientVertexArrayType type, const GLES1State &gles1);
     static int TexCoordArrayIndex(unsigned int unit);
-    AttributesMask getVertexArraysAttributeMask(const State *glState) const;
 
     void drawTexture(Context *context,
                      State *glState,
@@ -49,6 +48,8 @@
                      float width,
                      float height);
 
+    static constexpr int kTexUnitCount = 4;
+
   private:
     using Mat4Uniform = float[16];
     using Vec4Uniform = float[4];
@@ -84,7 +85,6 @@
 
     void setAttributesEnabled(Context *context, State *glState, AttributesMask mask);
 
-    static constexpr int kTexUnitCount   = 4;
     static constexpr int kLightCount     = 8;
     static constexpr int kClipPlaneCount = 6;
 
diff --git a/src/libANGLE/GLES1State.cpp b/src/libANGLE/GLES1State.cpp
index a2c83e9..425eb04 100644
--- a/src/libANGLE/GLES1State.cpp
+++ b/src/libANGLE/GLES1State.cpp
@@ -10,6 +10,7 @@
 #include "libANGLE/GLES1State.h"
 
 #include "libANGLE/Context.h"
+#include "libANGLE/GLES1Renderer.h"
 
 namespace gl
 {
@@ -416,4 +417,26 @@
     return mPointParameters;
 }
 
+AttributesMask GLES1State::getVertexArraysAttributeMask() const
+{
+    AttributesMask attribsMask;
+
+    ClientVertexArrayType nonTexcoordArrays[] = {
+        ClientVertexArrayType::Vertex, ClientVertexArrayType::Normal, ClientVertexArrayType::Color,
+        ClientVertexArrayType::PointSize,
+    };
+
+    for (const ClientVertexArrayType attrib : nonTexcoordArrays)
+    {
+        attribsMask.set(GLES1Renderer::VertexArrayIndex(attrib, *this),
+                        isClientStateEnabled(attrib));
+    }
+
+    for (unsigned int i = 0; i < GLES1Renderer::kTexUnitCount; i++)
+    {
+        attribsMask.set(GLES1Renderer::TexCoordArrayIndex(i), isTexCoordArrayEnabled(i));
+    }
+
+    return attribsMask;
+}
 }  // namespace gl
diff --git a/src/libANGLE/GLES1State.h b/src/libANGLE/GLES1State.h
index e477dd0..3d44b9d 100644
--- a/src/libANGLE/GLES1State.h
+++ b/src/libANGLE/GLES1State.h
@@ -190,6 +190,8 @@
     PointParameters &pointParameters();
     const PointParameters &pointParameters() const;
 
+    AttributesMask getVertexArraysAttributeMask() const;
+
   private:
     friend class State;
     friend class GLES1Renderer;
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 8422216..41deeb4 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -118,11 +118,7 @@
     const auto &vertexAttribs  = vao->getVertexAttributes();
     const auto &vertexBindings = vao->getVertexBindings();
 
-    bool isGLES1 = context->getClientVersion() < Version(2, 0);
-
-    const AttributesMask &activeAttribs = ((isGLES1 ? context->getVertexArraysAttributeMask()
-                                                    : program->getActiveAttribLocationsMask()) &
-                                           vao->getEnabledAttributesMask() & ~clientAttribs);
+    const AttributesMask &activeAttribs = context->getActiveBufferedAttribsMask();
 
     for (size_t attributeIndex : activeAttribs)
     {
@@ -130,7 +126,7 @@
         ASSERT(attrib.enabled);
 
         const VertexBinding &binding = vertexBindings[attrib.bindingIndex];
-        ASSERT(isGLES1 || program->isAttribLocationActive(attributeIndex));
+        ASSERT(context->isGLES1() || program->isAttribLocationActive(attributeIndex));
 
         GLint maxVertexElement = maxVertex;
         GLuint divisor         = binding.getDivisor();