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/tests/gl_tests/BlendMinMaxTest.cpp b/src/tests/gl_tests/BlendMinMaxTest.cpp
index 8ccaf92..39f5251 100644
--- a/src/tests/gl_tests/BlendMinMaxTest.cpp
+++ b/src/tests/gl_tests/BlendMinMaxTest.cpp
@@ -32,13 +32,12 @@
         float values[4];
     };
 
-    static GLubyte getExpected(bool blendMin, float curColor, GLubyte prevColor)
+    static float getExpected(bool blendMin, float curColor, float prevColor)
     {
-        GLubyte curAsUbyte = static_cast<GLubyte>((curColor * std::numeric_limits<GLubyte>::max()) + 0.5f);
-        return blendMin ? std::min<GLubyte>(curAsUbyte, prevColor) : std::max<GLubyte>(curAsUbyte, prevColor);
+        return blendMin ? std::min(curColor, prevColor) : std::max(curColor, prevColor);
     }
 
-    void runTest(GLenum colorFormat)
+    void runTest(GLenum colorFormat, GLenum type)
     {
         if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_blend_minmax"))
         {
@@ -55,17 +54,26 @@
 
         SetUpFramebuffer(colorFormat);
 
-        const size_t colorCount = 1024;
+        int minValue = 0;
+        int maxValue = 1;
+        if (type == GL_FLOAT)
+        {
+            minValue = -1024;
+            maxValue = 1024;
+        }
+
+        const size_t colorCount = 128;
         Color colors[colorCount];
         for (size_t i = 0; i < colorCount; i++)
         {
             for (size_t j = 0; j < 4; j++)
             {
-                colors[i].values[j] = (rand() % 255) / 255.0f;
+                colors[i].values[j] =
+                    static_cast<float>(minValue + (rand() % (maxValue - minValue)));
             }
         }
 
-        GLubyte prevColor[4];
+        float prevColor[4];
         for (size_t i = 0; i < colorCount; i++)
         {
             const Color &color = colors[i];
@@ -77,16 +85,37 @@
 
             drawQuad(mProgram, "aPosition", 0.5f);
 
-            if (i > 0)
+            float pixel[4];
+            if (type == GL_UNSIGNED_BYTE)
             {
-                EXPECT_PIXEL_EQ(0, 0,
-                                getExpected(blendMin, color.values[0], prevColor[0]),
-                                getExpected(blendMin, color.values[1], prevColor[1]),
-                                getExpected(blendMin, color.values[2], prevColor[2]),
-                                getExpected(blendMin, color.values[3], prevColor[3]));
+                GLubyte ubytePixel[4];
+                glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, ubytePixel);
+                for (size_t componentIdx = 0; componentIdx < ArraySize(pixel); componentIdx++)
+                {
+                    pixel[componentIdx] = ubytePixel[componentIdx] / 255.0f;
+                }
+            }
+            else if (type == GL_FLOAT)
+            {
+                glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, pixel);
+            }
+            else
+            {
+                FAIL() << "Unexpected pixel type";
             }
 
-            glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, prevColor);
+            if (i > 0)
+            {
+                const float errorRange = 1.0f / 255.0f;
+                for (size_t componentIdx = 0; componentIdx < ArraySize(pixel); componentIdx++)
+                {
+                    EXPECT_NEAR(
+                        getExpected(blendMin, color.values[componentIdx], prevColor[componentIdx]),
+                        pixel[componentIdx], errorRange);
+                }
+            }
+
+            memcpy(prevColor, pixel, sizeof(pixel));
         }
     }
 
@@ -142,6 +171,9 @@
         glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, getWindowWidth(), getWindowHeight());
         glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer);
 
+        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+        glClear(GL_COLOR_BUFFER_BIT);
+
         ASSERT_GL_NO_ERROR();
     }
 
@@ -163,10 +195,10 @@
 
 TEST_P(BlendMinMaxTest, RGBA8)
 {
-    runTest(GL_RGBA8);
+    runTest(GL_RGBA8, GL_UNSIGNED_BYTE);
 }
 
-TEST_P(BlendMinMaxTest, RGBA32f)
+TEST_P(BlendMinMaxTest, RGBA32F)
 {
     if (getClientMajorVersion() < 3 || !extensionEnabled("GL_EXT_color_buffer_float"))
     {
@@ -189,7 +221,7 @@
         return;
     }
 
-    runTest(GL_RGBA32F);
+    runTest(GL_RGBA32F, GL_FLOAT);
 }
 
 TEST_P(BlendMinMaxTest, RGBA16F)
@@ -208,21 +240,16 @@
         return;
     }
 
-    // TODO(geofflang): This fails because readpixels with UNSIGNED_BYTE/RGBA does not work with
-    // half float buffers (http://anglebug.com/1288)
-    if (GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
-    {
-        std::cout << "Test skipped on OpenGL ES targets." << std::endl;
-        return;
-    }
-
-    runTest(GL_RGBA16F);
+    runTest(GL_RGBA16F, GL_FLOAT);
 }
 
 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
 ANGLE_INSTANTIATE_TEST(BlendMinMaxTest,
                        ES2_D3D9(),
                        ES2_D3D11(),
+                       ES3_D3D11(),
                        ES2_D3D11_FL9_3(),
                        ES2_OPENGL(),
-                       ES2_OPENGLES());
+                       ES3_OPENGL(),
+                       ES2_OPENGLES(),
+                       ES3_OPENGLES());