Move end2end and standalone tests to gl_tests and egl_tests

Also introduce a test_utils directory that contains helpers used for all
types of tests.

BUG=angleproject:892

Change-Id: I9e1bff895020ffd3a109162283971a290a1098bd
Reviewed-on: https://chromium-review.googlesource.com/270198
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/tests/gl_tests/ReadPixelsTest.cpp b/src/tests/gl_tests/ReadPixelsTest.cpp
new file mode 100644
index 0000000..0929ed6
--- /dev/null
+++ b/src/tests/gl_tests/ReadPixelsTest.cpp
@@ -0,0 +1,349 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "test_utils/ANGLETest.h"
+
+using namespace angle;
+
+class ReadPixelsTest : public ANGLETest
+{
+  protected:
+    ReadPixelsTest()
+    {
+        setWindowWidth(32);
+        setWindowHeight(32);
+        setConfigRedBits(8);
+        setConfigGreenBits(8);
+        setConfigBlueBits(8);
+        setConfigAlphaBits(8);
+    }
+
+    virtual void SetUp()
+    {
+        ANGLETest::SetUp();
+
+        glGenBuffers(1, &mPBO);
+        glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
+        glBufferData(GL_PIXEL_PACK_BUFFER, 4 * getWindowWidth() * getWindowHeight(), NULL, GL_STATIC_DRAW);
+        glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+
+        const char *vertexShaderSrc = SHADER_SOURCE
+        (
+            attribute vec4 aTest;
+            attribute vec2 aPosition;
+            varying vec4 vTest;
+
+            void main()
+            {
+                vTest = aTest;
+                gl_Position = vec4(aPosition, 0.0, 1.0);
+                gl_PointSize = 1.0;
+            }
+        );
+
+        const char *fragmentShaderSrc = SHADER_SOURCE
+        (
+            precision mediump float;
+            varying vec4 vTest;
+
+            void main()
+            {
+                gl_FragColor = vTest;
+            }
+        );
+
+        mProgram = CompileProgram(vertexShaderSrc, fragmentShaderSrc);
+
+        glGenTextures(1, &mTexture);
+        glBindTexture(GL_TEXTURE_2D, mTexture);
+        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 4, 1);
+
+        glGenFramebuffers(1, &mFBO);
+        glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
+        glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+        glGenBuffers(1, &mPositionVBO);
+        glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
+        glBufferData(GL_ARRAY_BUFFER, 128, NULL, GL_DYNAMIC_DRAW);
+        glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+        ASSERT_GL_NO_ERROR();
+    }
+
+    virtual void TearDown()
+    {
+        ANGLETest::TearDown();
+
+        glDeleteBuffers(1, &mPBO);
+        glDeleteProgram(mProgram);
+        glDeleteTextures(1, &mTexture);
+        glDeleteFramebuffers(1, &mFBO);
+    }
+
+    GLuint mPBO;
+    GLuint mProgram;
+    GLuint mTexture;
+    GLuint mFBO;
+    GLuint mPositionVBO;
+};
+
+TEST_P(ReadPixelsTest, OutOfBounds)
+{
+    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_GL_NO_ERROR();
+
+    GLsizei pixelsWidth = 32;
+    GLsizei pixelsHeight = 32;
+    GLint offset = 16;
+    std::vector<GLubyte> pixels((pixelsWidth + offset) * (pixelsHeight + offset) * 4);
+
+    glReadPixels(-offset, -offset, pixelsWidth + offset, pixelsHeight + offset, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
+    EXPECT_GL_NO_ERROR();
+
+    for (int y = pixelsHeight / 2; y < pixelsHeight; y++)
+    {
+        for (int x = pixelsWidth / 2; x < pixelsWidth; x++)
+        {
+            const GLubyte* pixel = &pixels[0] + ((y * (pixelsWidth + offset) + x) * 4);
+            unsigned int r = static_cast<unsigned int>(pixel[0]);
+            unsigned int g = static_cast<unsigned int>(pixel[1]);
+            unsigned int b = static_cast<unsigned int>(pixel[2]);
+            unsigned int a = static_cast<unsigned int>(pixel[3]);
+
+            // Expect that all pixels which fell within the framebuffer are red
+            EXPECT_EQ(255, r);
+            EXPECT_EQ(0,   g);
+            EXPECT_EQ(0,   b);
+            EXPECT_EQ(255, a);
+        }
+    }
+}
+
+TEST_P(ReadPixelsTest, PBOWithOtherTarget)
+{
+    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_GL_NO_ERROR();
+
+    glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
+    glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+
+    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+    glBindBuffer(GL_ARRAY_BUFFER, mPBO);
+
+    GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
+    unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
+    EXPECT_GL_NO_ERROR();
+
+    EXPECT_EQ(255, dataPtr[0]);
+    EXPECT_EQ(0,   dataPtr[1]);
+    EXPECT_EQ(0,   dataPtr[2]);
+    EXPECT_EQ(255, dataPtr[3]);
+
+    glUnmapBuffer(GL_ARRAY_BUFFER);
+    EXPECT_GL_NO_ERROR();
+}
+
+TEST_P(ReadPixelsTest, PBOWithExistingData)
+{
+    // Clear backbuffer to red
+    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_GL_NO_ERROR();
+
+    // Read 16x16 region from red backbuffer to PBO
+    glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
+    glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+
+    // Clear backbuffer to green
+    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_GL_NO_ERROR();
+
+    // Read 16x16 region from green backbuffer to PBO at offset 16
+    glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<GLvoid*>(16));
+    GLvoid * mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT);
+    unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
+    EXPECT_GL_NO_ERROR();
+
+    // Test pixel 0 is red (existing data)
+    EXPECT_EQ(255, dataPtr[0]);
+    EXPECT_EQ(0, dataPtr[1]);
+    EXPECT_EQ(0, dataPtr[2]);
+    EXPECT_EQ(255, dataPtr[3]);
+
+    // Test pixel 16 is green (new data)
+    EXPECT_EQ(0, dataPtr[16 * 4 + 0]);
+    EXPECT_EQ(255, dataPtr[16 * 4 + 1]);
+    EXPECT_EQ(0, dataPtr[16 * 4 + 2]);
+    EXPECT_EQ(255, dataPtr[16 * 4 + 3]);
+
+    glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
+    EXPECT_GL_NO_ERROR();
+}
+
+TEST_P(ReadPixelsTest, PBOAndSubData)
+{
+    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_GL_NO_ERROR();
+
+    glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
+    glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+
+    unsigned char data[4] = { 1, 2, 3, 4 };
+
+    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+    glBindBuffer(GL_ARRAY_BUFFER, mPBO);
+    glBufferSubData(GL_ARRAY_BUFFER, 0, 4, data);
+
+    GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
+    unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
+    EXPECT_GL_NO_ERROR();
+
+    EXPECT_EQ(1, dataPtr[0]);
+    EXPECT_EQ(2, dataPtr[1]);
+    EXPECT_EQ(3, dataPtr[2]);
+    EXPECT_EQ(4, dataPtr[3]);
+
+    glUnmapBuffer(GL_ARRAY_BUFFER);
+    EXPECT_GL_NO_ERROR();
+}
+
+TEST_P(ReadPixelsTest, PBOAndSubDataOffset)
+{
+    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_GL_NO_ERROR();
+
+    glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
+    glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+
+    unsigned char data[4] = { 1, 2, 3, 4 };
+
+    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+    glBindBuffer(GL_ARRAY_BUFFER, mPBO);
+    glBufferSubData(GL_ARRAY_BUFFER, 16, 4, data);
+
+    GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
+    unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
+    EXPECT_GL_NO_ERROR();
+
+    EXPECT_EQ(255, dataPtr[0]);
+    EXPECT_EQ(0, dataPtr[1]);
+    EXPECT_EQ(0, dataPtr[2]);
+    EXPECT_EQ(255, dataPtr[3]);
+
+    EXPECT_EQ(1, dataPtr[16]);
+    EXPECT_EQ(2, dataPtr[17]);
+    EXPECT_EQ(3, dataPtr[18]);
+    EXPECT_EQ(4, dataPtr[19]);
+
+    glUnmapBuffer(GL_ARRAY_BUFFER);
+    EXPECT_GL_NO_ERROR();
+}
+
+TEST_P(ReadPixelsTest, DrawWithPBO)
+{
+    unsigned char data[4] = { 1, 2, 3, 4 };
+
+    glBindTexture(GL_TEXTURE_2D, mTexture);
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
+    EXPECT_GL_NO_ERROR();
+
+    // glReadBuffer(GL_COLOR_ATTACHMENT0); // FIXME: currently UNIMPLEMENTED
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, mFBO);
+    EXPECT_GL_NO_ERROR();
+
+    glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
+    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+    EXPECT_GL_NO_ERROR();
+
+    float positionData[] = { 0.5f, 0.5f };
+
+    glUseProgram(mProgram);
+    glViewport(0, 0, 1, 1);
+    glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
+    glBufferSubData(GL_ARRAY_BUFFER, 0, 1 * 2 * 4, positionData);
+    EXPECT_GL_NO_ERROR();
+
+    GLint positionLocation = glGetAttribLocation(mProgram, "aPosition");
+    EXPECT_NE(-1, positionLocation);
+
+    GLint testLocation = glGetAttribLocation(mProgram, "aTest");
+    EXPECT_NE(-1, testLocation);
+
+    glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
+    glEnableVertexAttribArray(positionLocation);
+    EXPECT_GL_NO_ERROR();
+
+    glBindBuffer(GL_ARRAY_BUFFER, mPBO);
+    glVertexAttribPointer(testLocation, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
+    glEnableVertexAttribArray(testLocation);
+    EXPECT_GL_NO_ERROR();
+
+    glDrawArrays(GL_POINTS, 0, 1);
+    EXPECT_GL_NO_ERROR();
+
+    memset(data, 0, 4);
+    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
+    EXPECT_GL_NO_ERROR();
+
+    EXPECT_EQ(1, data[0]);
+    EXPECT_EQ(2, data[1]);
+    EXPECT_EQ(3, data[2]);
+    EXPECT_EQ(4, data[3]);
+}
+
+TEST_P(ReadPixelsTest, MultisampledPBO)
+{
+    if (getClientVersion() < 3 && !extensionEnabled("GL_ANGLE_framebuffer_multisample"))
+    {
+        std::cout << "Test skipped because ES3 or GL_ANGLE_framebuffer_multisample is not available." << std::endl;
+        return;
+    }
+
+    GLuint fbo;
+    glGenFramebuffers(1, &fbo);
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+    GLuint rbo;
+    glGenRenderbuffers(1, &rbo);
+    glBindRenderbuffer(GL_RENDERBUFFER, rbo);
+
+    if (extensionEnabled("GL_ANGLE_framebuffer_multisample"))
+    {
+        glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4);
+    }
+    else
+    {
+        glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4);
+    }
+
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
+
+    ASSERT_GL_NO_ERROR();
+
+    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
+
+    EXPECT_GL_NO_ERROR();
+
+    glReadPixels(0, 0, 1, 1, GL_RGBA8, GL_UNSIGNED_BYTE, NULL);
+
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    glDeleteRenderbuffers(1, &rbo);
+    glDeleteFramebuffers(1, &fbo);
+}
+
+// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
+ANGLE_INSTANTIATE_TEST(ReadPixelsTest, ES3_D3D11());