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/renderer/d3d/FramebufferD3D.cpp b/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
index a45c945..a272264 100644
--- a/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
+++ b/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
@@ -207,7 +207,7 @@
     GLenum implementationFormat = getRenderTargetImplementationFormat(attachmentRenderTarget);
     const gl::InternalFormat &implementationFormatInfo = gl::GetInternalFormatInfo(implementationFormat);
 
-    return implementationFormatInfo.format;
+    return implementationFormatInfo.getReadPixelsFormat();
 }
 
 GLenum FramebufferD3D::getImplementationColorReadType() const
@@ -229,7 +229,7 @@
     GLenum implementationFormat = getRenderTargetImplementationFormat(attachmentRenderTarget);
     const gl::InternalFormat &implementationFormatInfo = gl::GetInternalFormatInfo(implementationFormat);
 
-    return implementationFormatInfo.type;
+    return implementationFormatInfo.getReadPixelsType();
 }
 
 gl::Error FramebufferD3D::readPixels(ContextImpl *context,
diff --git a/src/libANGLE/renderer/gl/FramebufferGL.cpp b/src/libANGLE/renderer/gl/FramebufferGL.cpp
index 4606114..8d84c60 100644
--- a/src/libANGLE/renderer/gl/FramebufferGL.cpp
+++ b/src/libANGLE/renderer/gl/FramebufferGL.cpp
@@ -21,6 +21,7 @@
 #include "libANGLE/renderer/gl/StateManagerGL.h"
 #include "libANGLE/renderer/gl/TextureGL.h"
 #include "libANGLE/renderer/gl/WorkaroundsGL.h"
+#include "libANGLE/renderer/gl/formatutilsgl.h"
 #include "platform/Platform.h"
 
 using namespace gl;
@@ -212,14 +213,14 @@
 {
     const auto *readAttachment = mState.getReadAttachment();
     const Format &format       = readAttachment->getFormat();
-    return format.info->format;
+    return format.info->getReadPixelsFormat();
 }
 
 GLenum FramebufferGL::getImplementationColorReadType() const
 {
     const auto *readAttachment = mState.getReadAttachment();
     const Format &format       = readAttachment->getFormat();
-    return format.info->type;
+    return format.info->getReadPixelsType();
 }
 
 Error FramebufferGL::readPixels(ContextImpl *context,
@@ -234,7 +235,11 @@
     mStateManager->setPixelPackState(packState);
 
     mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, mFramebufferID);
-    mFunctions->readPixels(area.x, area.y, area.width, area.height, format, type, pixels);
+
+    nativegl::ReadPixelsFormat readPixelsFormat =
+        nativegl::GetReadPixelsFormat(mFunctions, mWorkarounds, format, type);
+    mFunctions->readPixels(area.x, area.y, area.width, area.height, readPixelsFormat.format,
+                           readPixelsFormat.type, pixels);
 
     return Error(GL_NO_ERROR);
 }
diff --git a/src/libANGLE/renderer/gl/formatutilsgl.cpp b/src/libANGLE/renderer/gl/formatutilsgl.cpp
index 1688be1..c5219b4 100644
--- a/src/libANGLE/renderer/gl/formatutilsgl.cpp
+++ b/src/libANGLE/renderer/gl/formatutilsgl.cpp
@@ -438,6 +438,32 @@
     return result;
 }
 
+static GLenum GetNativeReadType(const FunctionsGL *functions,
+                                const WorkaroundsGL &workarounds,
+                                GLenum type)
+{
+    GLenum result = type;
+
+    if (functions->standard == STANDARD_GL_DESKTOP)
+    {
+        if (type == GL_HALF_FLOAT_OES)
+        {
+            // The enums differ for the OES half float extensions and desktop GL spec. Update it.
+            result = GL_HALF_FLOAT;
+        }
+    }
+
+    return result;
+}
+
+static GLenum GetNativeReadFormat(const FunctionsGL *functions,
+                                  const WorkaroundsGL &workarounds,
+                                  GLenum format)
+{
+    GLenum result = format;
+    return result;
+}
+
 TexImageFormat GetTexImageFormat(const FunctionsGL *functions,
                                  const WorkaroundsGL &workarounds,
                                  GLenum internalFormat,
@@ -512,6 +538,16 @@
         GetNativeInternalFormat(functions, workarounds, internalFormat, internalFormat);
     return result;
 }
+ReadPixelsFormat GetReadPixelsFormat(const FunctionsGL *functions,
+                                     const WorkaroundsGL &workarounds,
+                                     GLenum format,
+                                     GLenum type)
+{
+    ReadPixelsFormat result;
+    result.format = GetNativeReadFormat(functions, workarounds, format);
+    result.type   = GetNativeReadType(functions, workarounds, type);
+    return result;
+}
 }
 
 }
diff --git a/src/libANGLE/renderer/gl/formatutilsgl.h b/src/libANGLE/renderer/gl/formatutilsgl.h
index 547d478..616f37a 100644
--- a/src/libANGLE/renderer/gl/formatutilsgl.h
+++ b/src/libANGLE/renderer/gl/formatutilsgl.h
@@ -112,6 +112,16 @@
 RenderbufferFormat GetRenderbufferFormat(const FunctionsGL *functions,
                                          const WorkaroundsGL &workarounds,
                                          GLenum internalFormat);
+
+struct ReadPixelsFormat
+{
+    GLenum format;
+    GLenum type;
+};
+ReadPixelsFormat GetReadPixelsFormat(const FunctionsGL *functions,
+                                     const WorkaroundsGL &workarounds,
+                                     GLenum format,
+                                     GLenum type);
 }
 
 }