Implement robust GetVertexAttrib entry points.

BUG=angleproject:1354

Change-Id: Ic71392555ae4212c4144bc67d7c5e53874af4d53
Reviewed-on: https://chromium-review.googlesource.com/398198
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/queryutils.cpp b/src/libANGLE/queryutils.cpp
index 542834f..9914029 100644
--- a/src/libANGLE/queryutils.cpp
+++ b/src/libANGLE/queryutils.cpp
@@ -17,6 +17,7 @@
 #include "libANGLE/Sampler.h"
 #include "libANGLE/Shader.h"
 #include "libANGLE/Texture.h"
+#include "libANGLE/VertexAttribute.h"
 
 namespace gl
 {
@@ -239,6 +240,62 @@
     }
 }
 
+template <typename ParamType, typename CurrentDataType>
+ParamType ConvertCurrentValue(CurrentDataType currentValue)
+{
+    return static_cast<ParamType>(currentValue);
+}
+
+template <>
+GLint ConvertCurrentValue(GLfloat currentValue)
+{
+    return iround<GLint>(currentValue);
+}
+
+template <typename ParamType, typename CurrentDataType, size_t CurrentValueCount>
+void QueryVertexAttribBase(const VertexAttribute &attrib,
+                           const CurrentDataType (&currentValueData)[CurrentValueCount],
+                           GLenum pname,
+                           ParamType *params)
+{
+    switch (pname)
+    {
+        case GL_CURRENT_VERTEX_ATTRIB:
+            for (size_t i = 0; i < CurrentValueCount; ++i)
+            {
+                params[i] = ConvertCurrentValue<ParamType>(currentValueData[i]);
+            }
+            break;
+        case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
+            *params = ConvertFromGLboolean<ParamType>(attrib.enabled);
+            break;
+        case GL_VERTEX_ATTRIB_ARRAY_SIZE:
+            *params = ConvertFromGLuint<ParamType>(attrib.size);
+            break;
+        case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
+            *params = ConvertFromGLuint<ParamType>(attrib.stride);
+            break;
+        case GL_VERTEX_ATTRIB_ARRAY_TYPE:
+            *params = ConvertFromGLenum<ParamType>(attrib.type);
+            break;
+        case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
+            *params = ConvertFromGLboolean<ParamType>(attrib.normalized);
+            break;
+        case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+            *params = ConvertFromGLuint<ParamType>(attrib.buffer.id());
+            break;
+        case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
+            *params = ConvertFromGLuint<ParamType>(attrib.divisor);
+            break;
+        case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
+            *params = ConvertFromGLboolean<ParamType>(attrib.pureInteger);
+            break;
+        default:
+            UNREACHABLE();
+            break;
+    }
+}
+
 }  // anonymous namespace
 
 void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer,
@@ -521,6 +578,52 @@
     QuerySamplerParameterBase(sampler, pname, params);
 }
 
+void QueryVertexAttribfv(const VertexAttribute &attrib,
+                         const VertexAttribCurrentValueData &currentValueData,
+                         GLenum pname,
+                         GLfloat *params)
+{
+    QueryVertexAttribBase(attrib, currentValueData.FloatValues, pname, params);
+}
+
+void QueryVertexAttribiv(const VertexAttribute &attrib,
+                         const VertexAttribCurrentValueData &currentValueData,
+                         GLenum pname,
+                         GLint *params)
+{
+    QueryVertexAttribBase(attrib, currentValueData.FloatValues, pname, params);
+}
+
+void QueryVertexAttribPointerv(const VertexAttribute &attrib, GLenum pname, GLvoid **pointer)
+{
+    switch (pname)
+    {
+        case GL_VERTEX_ATTRIB_ARRAY_POINTER:
+            *pointer = const_cast<GLvoid *>(attrib.pointer);
+            break;
+
+        default:
+            UNREACHABLE();
+            break;
+    }
+}
+
+void QueryVertexAttribIiv(const VertexAttribute &attrib,
+                          const VertexAttribCurrentValueData &currentValueData,
+                          GLenum pname,
+                          GLint *params)
+{
+    QueryVertexAttribBase(attrib, currentValueData.IntValues, pname, params);
+}
+
+void QueryVertexAttribIuiv(const VertexAttribute &attrib,
+                           const VertexAttribCurrentValueData &currentValueData,
+                           GLenum pname,
+                           GLuint *params)
+{
+    QueryVertexAttribBase(attrib, currentValueData.UnsignedIntValues, pname, params);
+}
+
 void SetTexParameterf(Texture *texture, GLenum pname, GLfloat param)
 {
     SetTexParameterBase(texture, pname, &param);