Fix validation of ReadPixels format and type.

The validation for ReadPixels allows for two combations of format/type:
  1. Based on the current framebuffer's component type.
    * GL_RGBA/GL_UNSIGNED_BYTE if the framebuffer is a normalized (signed
      or unsigned).
    * GL_RGBA_INTEGER/GL_INTEGER if the framebuffer is an
      integer format.
    * GL_RGBA_INTEGER/GL_UNSIGNED_INTEGER if the framebuffer is an
      unsigned integer format.
    * GL_RGBA/GL_FLOAT if the framebuffer is any type of float
      framebuffer (added in EXT_color_buffer_float).
    * These combations are detailed in the ES2 spec on pg 105 or ES3 on pg
      193.
  2. The implementation read format/type returned from glGetIntegerv.
    * These formats are added by specs, OES_texture_float, EXT_texture_rg,
      EXT_read_format_bgra, etc.

Update the GL and D3D backends to perform the conversion from GL_HALF_FLOAT
to GL_HALF_FLOAT_OES.

Continue allowing reading as BGRA_EXT to support Skia.  Should be removed in
the future.

BUG=607283
BUG=angleproject:1478

Change-Id: I0312cad4d5f138ab036f383d221f8ccd19a77f6d
Reviewed-on: https://chromium-review.googlesource.com/346232
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 0846f0d..d204d67 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -99,6 +99,38 @@
     return true;
 }
 
+bool ValidReadPixelsFormatType(ValidationContext *context,
+                               GLenum framebufferComponentType,
+                               GLenum format,
+                               GLenum type)
+{
+    switch (framebufferComponentType)
+    {
+        case GL_UNSIGNED_NORMALIZED:
+            // TODO(geofflang): Don't accept BGRA here.  Some chrome internals appear to try to use
+            // ReadPixels with BGRA even if the extension is not present
+            return (format == GL_RGBA && type == GL_UNSIGNED_BYTE) ||
+                   (context->getExtensions().readFormatBGRA && format == GL_BGRA_EXT &&
+                    type == GL_UNSIGNED_BYTE);
+
+        case GL_SIGNED_NORMALIZED:
+            return (format == GL_RGBA && type == GL_UNSIGNED_BYTE);
+
+        case GL_INT:
+            return (format == GL_RGBA_INTEGER && type == GL_INT);
+
+        case GL_UNSIGNED_INT:
+            return (format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT);
+
+        case GL_FLOAT:
+            return (format == GL_RGBA && type == GL_FLOAT);
+
+        default:
+            UNREACHABLE();
+            return false;
+    }
+}
+
 }  // anonymous namespace
 
 bool ValidCap(const Context *context, GLenum cap)
@@ -1122,12 +1154,12 @@
     GLenum currentFormat = framebuffer->getImplementationColorReadFormat();
     GLenum currentType = framebuffer->getImplementationColorReadType();
     GLenum currentInternalFormat = readBuffer->getFormat().asSized();
-    GLuint clientVersion         = context->getClientMajorVersion();
 
-    bool validReadFormat = (clientVersion < 3) ? ValidES2ReadFormatType(context, format, type) :
-                                                 ValidES3ReadFormatType(context, currentInternalFormat, format, type);
+    const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(currentInternalFormat);
+    bool validFormatTypeCombination =
+        ValidReadPixelsFormatType(context, internalFormatInfo.componentType, format, type);
 
-    if (!(currentFormat == format && currentType == type) && !validReadFormat)
+    if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
     {
         context->handleError(Error(GL_INVALID_OPERATION));
         return false;