//
// 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.
//

#ifdef UNSAFE_BUFFERS_BUILD
#    pragma allow_unsafe_buffers
#endif

#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
#include "util/EGLWindow.h"

using namespace angle;

class PbufferTest : public ANGLETest<>
{
  protected:
    PbufferTest()
    {
        setWindowWidth(512);
        setWindowHeight(512);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }

    void testSetUp() override
    {
        constexpr char kVS[] =
            R"(precision highp float;
            attribute vec4 position;
            varying vec2 texcoord;

            void main()
            {
                gl_Position = position;
                texcoord = (position.xy * 0.5) + 0.5;
                texcoord.y = 1.0 - texcoord.y;
            })";

        constexpr char kFS[] =
            R"(precision highp float;
            uniform sampler2D tex;
            varying vec2 texcoord;

            void main()
            {
                gl_FragColor = texture2D(tex, texcoord);
            })";

        mTextureProgram = CompileProgram(kVS, kFS);
        if (mTextureProgram == 0)
        {
            FAIL() << "shader compilation failed.";
        }

        mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");

        EGLWindow *window = getEGLWindow();

        EGLint surfaceType = 0;
        eglGetConfigAttrib(window->getDisplay(), window->getConfig(), EGL_SURFACE_TYPE,
                           &surfaceType);
        mSupportsPbuffers = (surfaceType & EGL_PBUFFER_BIT) != 0;

        mPbuffer = createTestPbufferSurface();
        if (mSupportsPbuffers)
        {
            ASSERT_NE(mPbuffer, EGL_NO_SURFACE);
            ASSERT_EGL_SUCCESS();
        }
        else
        {
            ASSERT_EQ(mPbuffer, EGL_NO_SURFACE);
            ASSERT_EGL_ERROR(EGL_BAD_MATCH);
        }
        ASSERT_GL_NO_ERROR();
    }

    EGLSurface createTestPbufferSurface()
    {
        EGLWindow *window        = getEGLWindow();
        EGLint bindToTextureRGBA = 0;
        eglGetConfigAttrib(window->getDisplay(), window->getConfig(), EGL_BIND_TO_TEXTURE_RGBA,
                           &bindToTextureRGBA);
        mSupportsBindTexImage = (bindToTextureRGBA == EGL_TRUE);

        const EGLint pBufferAttributes[] = {
            EGL_WIDTH,          static_cast<EGLint>(mPbufferSize),
            EGL_HEIGHT,         static_cast<EGLint>(mPbufferSize),
            EGL_TEXTURE_FORMAT, mSupportsBindTexImage ? EGL_TEXTURE_RGBA : EGL_NO_TEXTURE,
            EGL_TEXTURE_TARGET, mSupportsBindTexImage ? EGL_TEXTURE_2D : EGL_NO_TEXTURE,
            EGL_NONE,           EGL_NONE,
        };

        return eglCreatePbufferSurface(window->getDisplay(), window->getConfig(),
                                       pBufferAttributes);
    }

    void testTearDown() override
    {
        glDeleteProgram(mTextureProgram);

        destroyPbuffer();
    }

    void destroyPbuffer()
    {
        if (mPbuffer)
        {
            destroyTestPbufferSurface(mPbuffer);
        }
    }

    void destroyTestPbufferSurface(EGLSurface pbuffer)
    {
        EGLWindow *window = getEGLWindow();
        eglDestroySurface(window->getDisplay(), pbuffer);
    }

    void recreatePbufferInSrgbColorspace()
    {
        EGLWindow *window = getEGLWindow();

        destroyPbuffer();

        const EGLint pBufferSrgbAttributes[] = {
            EGL_WIDTH,
            static_cast<EGLint>(mPbufferSize),
            EGL_HEIGHT,
            static_cast<EGLint>(mPbufferSize),
            EGL_TEXTURE_FORMAT,
            mSupportsBindTexImage ? EGL_TEXTURE_RGBA : EGL_NO_TEXTURE,
            EGL_TEXTURE_TARGET,
            mSupportsBindTexImage ? EGL_TEXTURE_2D : EGL_NO_TEXTURE,
            EGL_GL_COLORSPACE_KHR,
            EGL_GL_COLORSPACE_SRGB_KHR,
            EGL_NONE,
            EGL_NONE,
        };

        mPbuffer = eglCreatePbufferSurface(window->getDisplay(), window->getConfig(),
                                           pBufferSrgbAttributes);
    }

    void drawColorQuad(GLColor color)
    {
        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
        glUseProgram(program);
        GLint colorUniformLocation =
            glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
        ASSERT_NE(colorUniformLocation, -1);
        glUniform4fv(colorUniformLocation, 1, color.toNormalizedVector().data());
        drawQuad(program, essl1_shaders::PositionAttrib(), 0);
        glUseProgram(0);
    }

    GLuint mTextureProgram;
    GLint mTextureUniformLocation;

    const size_t mPbufferSize = 32;
    EGLSurface mPbuffer       = EGL_NO_SURFACE;
    bool mSupportsPbuffers;
    bool mSupportsBindTexImage;
};

class PbufferColorspaceTest : public PbufferTest
{};

// Test clearing a Pbuffer and checking the color is correct
TEST_P(PbufferTest, Clearing)
{
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers);

    EGLWindow *window = getEGLWindow();

    // Clear the window surface to blue and verify
    window->makeCurrent();
    ASSERT_EGL_SUCCESS();

    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue);

    // Apply the Pbuffer and clear it to purple and verify
    eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext());
    ASSERT_EGL_SUCCESS();

    glViewport(0, 0, static_cast<GLsizei>(mPbufferSize), static_cast<GLsizei>(mPbufferSize));
    glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_EQ(static_cast<GLint>(mPbufferSize) / 2, static_cast<GLint>(mPbufferSize) / 2, 255,
                    0, 255, 255);

    // Rebind the window surface and verify that it is still blue
    window->makeCurrent();
    ASSERT_EGL_SUCCESS();
    EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 255, 255);
}

// Bind the Pbuffer to a texture and verify it renders correctly
TEST_P(PbufferTest, BindTexImage)
{
    // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
    // textures.
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);

    EGLWindow *window = getEGLWindow();

    // Apply the Pbuffer and clear it to purple
    eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext());
    ASSERT_EGL_SUCCESS();

    glViewport(0, 0, static_cast<GLsizei>(mPbufferSize), static_cast<GLsizei>(mPbufferSize));
    glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(mPbufferSize) / 2,
                          static_cast<GLint>(mPbufferSize) / 2, GLColor::magenta);

    // Apply the window surface
    window->makeCurrent();

    // Create a texture and bind the Pbuffer to it
    GLuint texture = 0;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    EXPECT_GL_NO_ERROR();

    eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
    glViewport(0, 0, getWindowWidth(), getWindowHeight());
    ASSERT_EGL_SUCCESS();

    // Draw a quad and verify that it is purple
    glUseProgram(mTextureProgram);
    glUniform1i(mTextureUniformLocation, 0);

    drawQuad(mTextureProgram, "position", 0.5f);
    EXPECT_GL_NO_ERROR();

    // Unbind the texture
    eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
    ASSERT_EGL_SUCCESS();

    // Verify that purple was drawn
    EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 255, 255);

    glDeleteTextures(1, &texture);
}

// Test various EGL level cases for eglBindTexImage.
TEST_P(PbufferTest, BindTexImageAlreadyBound)
{
    // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
    // textures.
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);
    EGLWindow *window = getEGLWindow();
    window->makeCurrent();

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_GL_NO_ERROR();

    // This is being tested
    EXPECT_TRUE(eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER));
    ASSERT_EGL_SUCCESS();
    // If buffer is already bound to a texture then an EGL_BAD_ACCESS error is returned.
    EXPECT_FALSE(eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER));
    ASSERT_EGL_ERROR(EGL_BAD_ACCESS);

    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    ANGLE_SKIP_TEST_IF(status == GL_FRAMEBUFFER_UNSUPPORTED);
    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);

    drawColorQuad(GLColor::magenta);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(mPbufferSize) / 2,
                          static_cast<GLint>(mPbufferSize) / 2, GLColor::magenta);

    destroyPbuffer();
    ASSERT_EGL_SUCCESS();
    ASSERT_GL_NO_ERROR();
}

// Test that eglBindTexImage overwriting previous bind works.
TEST_P(PbufferTest, BindTexImageOverwrite)
{
    // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
    // textures.
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);

    EGLWindow *window = getEGLWindow();
    window->makeCurrent();

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_GL_NO_ERROR();

    // This is being tested: setup a binding that will be overwritten.
    EXPECT_TRUE(eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER));
    ASSERT_EGL_SUCCESS();

    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    ANGLE_SKIP_TEST_IF(status == GL_FRAMEBUFFER_UNSUPPORTED);
    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);

    drawColorQuad(GLColor::magenta);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(mPbufferSize) / 2,
                          static_cast<GLint>(mPbufferSize) / 2, GLColor::magenta);

    EGLSurface otherPbuffer = createTestPbufferSurface();
    ASSERT_NE(otherPbuffer, EGL_NO_SURFACE);
    // This is being tested: replace the previous binding.
    EXPECT_TRUE(eglBindTexImage(window->getDisplay(), otherPbuffer, EGL_BACK_BUFFER));
    ASSERT_EGL_SUCCESS();

    drawColorQuad(GLColor::yellow);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(mPbufferSize) / 2,
                          static_cast<GLint>(mPbufferSize) / 2, GLColor::yellow);

    destroyTestPbufferSurface(otherPbuffer);
    destroyPbuffer();
    ASSERT_EGL_SUCCESS();
    ASSERT_GL_NO_ERROR();
}

// Test that eglBindTexImage overwriting previous bind works and does not crash on releaseTexImage.
TEST_P(PbufferTest, BindTexImageOverwriteNoCrashOnReleaseTexImage)
{
    // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
    // textures.
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);
    EGLWindow *window = getEGLWindow();
    window->makeCurrent();

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    EXPECT_GL_NO_ERROR();

    EGLSurface otherPbuffer = createTestPbufferSurface();
    ASSERT_NE(otherPbuffer, EGL_NO_SURFACE);

    EXPECT_TRUE(eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER));
    ASSERT_EGL_SUCCESS();
    EXPECT_TRUE(eglBindTexImage(window->getDisplay(), otherPbuffer, EGL_BACK_BUFFER));
    ASSERT_EGL_SUCCESS();
    EXPECT_TRUE(eglReleaseTexImage(window->getDisplay(), otherPbuffer, EGL_BACK_BUFFER));
    ASSERT_EGL_SUCCESS();
    EXPECT_TRUE(eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER));  // No-op.
    ASSERT_EGL_SUCCESS();
    EXPECT_TRUE(eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER));
    ASSERT_EGL_SUCCESS();
    EXPECT_TRUE(eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER));
    ASSERT_EGL_SUCCESS();

    destroyTestPbufferSurface(otherPbuffer);
    destroyPbuffer();
    ASSERT_EGL_SUCCESS();
    ASSERT_GL_NO_ERROR();
}

// Test that eglBindTexImage pbuffer is unbound when the texture is destroyed.
TEST_P(PbufferTest, BindTexImageReleaseViaTextureDestroy)
{
    // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
    // textures.
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);
    EGLWindow *window = getEGLWindow();
    window->makeCurrent();

    // Bind to a texture that will be destroyed.
    {
        GLTexture texture;
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
        EXPECT_GL_NO_ERROR();

        // This is being tested: setup a binding that will be overwritten.
        EXPECT_TRUE(eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER));
        ASSERT_EGL_SUCCESS();

        GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
        ANGLE_SKIP_TEST_IF(status == GL_FRAMEBUFFER_UNSUPPORTED);
        EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);

        drawColorQuad(GLColor::magenta);
        ASSERT_GL_NO_ERROR();
    }

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_GL_NO_ERROR();

    // This is being tested.
    EXPECT_TRUE(eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER));
    ASSERT_EGL_SUCCESS();

    EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(mPbufferSize) / 2,
                          static_cast<GLint>(mPbufferSize) / 2, GLColor::magenta);

    destroyPbuffer();
    ASSERT_EGL_SUCCESS();
    ASSERT_GL_NO_ERROR();
}

// Test that eglBindTexImage pbuffer is unbound when eglReleaseTexImage is called.
TEST_P(PbufferTest, BindTexImagePbufferReleaseWhileBoundToFBOColorBuffer)
{
    // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
    // textures.
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);
    EGLWindow *window = getEGLWindow();
    window->makeCurrent();

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_GL_NO_ERROR();

    // This is being tested: setup a binding to a pbuffer that will be unbound.
    EXPECT_TRUE(eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER));
    ASSERT_EGL_SUCCESS();

    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    ANGLE_SKIP_TEST_IF(status == GL_FRAMEBUFFER_UNSUPPORTED);
    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);

    // This is being tested: unbind the pbuffer, detect it via framebuffer status.
    EXPECT_TRUE(eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER));
    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, status);

    destroyPbuffer();
    ASSERT_EGL_SUCCESS();
    ASSERT_GL_NO_ERROR();
}

// Test that eglBindTexImage pbuffer is bound when the pbuffer is destroyed.
TEST_P(PbufferTest, BindTexImagePbufferDestroyWhileBound)
{
    // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
    // textures.
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);
    EGLWindow *window = getEGLWindow();
    window->makeCurrent();

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_GL_NO_ERROR();

    // This is being tested: setup a binding to a pbuffer that will be destroyed.
    EXPECT_TRUE(eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER));
    ASSERT_EGL_SUCCESS();

    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    ANGLE_SKIP_TEST_IF(status == GL_FRAMEBUFFER_UNSUPPORTED);
    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);

    drawColorQuad(GLColor::magenta);
    ASSERT_GL_NO_ERROR();

    // This is being tested: destroy the pbuffer, but the underlying binding still works.
    destroyPbuffer();
    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);

    EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(mPbufferSize) / 2,
                          static_cast<GLint>(mPbufferSize) / 2, GLColor::magenta);

    ASSERT_EGL_SUCCESS();
    ASSERT_GL_NO_ERROR();
}

// Test that eglBindTexImage overwrite releases the previous pbuffer if the previous is orphaned.
TEST_P(PbufferTest, BindTexImageOverwriteReleasesOrphanedPbuffer)
{
    // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
    // textures.
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);

    EGLWindow *window = getEGLWindow();
    window->makeCurrent();

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_GL_NO_ERROR();

    // This is being tested: setup a binding to a pbuffer that will be destroyed.
    EXPECT_TRUE(eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER));
    ASSERT_EGL_SUCCESS();

    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    ANGLE_SKIP_TEST_IF(status == GL_FRAMEBUFFER_UNSUPPORTED);
    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);

    // Write magenta. This shouldn't be read below.
    drawColorQuad(GLColor::magenta);
    ASSERT_GL_NO_ERROR();

    // This is being tested: destroy the pbuffer, but the underlying binding still works.
    destroyPbuffer();
    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);

    EGLSurface otherPbuffer = createTestPbufferSurface();
    // This is being tested: bind a new pbuffer. The one orphaned above will now be really
    // deallocated and we hope some sort of assert fires if something goes wrong.
    EXPECT_TRUE(eglBindTexImage(window->getDisplay(), otherPbuffer, EGL_BACK_BUFFER));

    // Write yellow.
    drawColorQuad(GLColor::yellow);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(mPbufferSize) / 2,
                          static_cast<GLint>(mPbufferSize) / 2, GLColor::yellow);

    destroyTestPbufferSurface(otherPbuffer);
    ASSERT_EGL_SUCCESS();
    ASSERT_GL_NO_ERROR();
}

// Verify that binding a pbuffer works after using a texture normally.
TEST_P(PbufferTest, BindTexImageAfterTexImage)
{
    // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
    // textures.
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);

    EGLWindow *window = getEGLWindow();

    // Apply the Pbuffer and clear it to magenta
    eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext());
    ASSERT_EGL_SUCCESS();

    glViewport(0, 0, static_cast<GLsizei>(mPbufferSize), static_cast<GLsizei>(mPbufferSize));
    glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(static_cast<GLint>(mPbufferSize) / 2,
                          static_cast<GLint>(mPbufferSize) / 2, GLColor::magenta);

    // Apply the window surface
    window->makeCurrent();
    glViewport(0, 0, getWindowWidth(), getWindowHeight());

    // Create a simple blue texture.
    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::blue);
    EXPECT_GL_NO_ERROR();

    // Draw a quad and verify blue
    glUseProgram(mTextureProgram);
    glUniform1i(mTextureUniformLocation, 0);
    drawQuad(mTextureProgram, "position", 0.5f);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);

    // Bind the Pbuffer to the texture
    eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
    ASSERT_EGL_SUCCESS();

    // Draw a quad and verify magenta
    drawQuad(mTextureProgram, "position", 0.5f);
    EXPECT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);

    // Unbind the texture
    eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
    ASSERT_EGL_SUCCESS();
}

// Test clearing a Pbuffer in sRGB colorspace and checking the color is correct.
// Then bind the Pbuffer to a texture and verify it renders correctly
TEST_P(PbufferTest, ClearAndBindTexImageSrgb)
{
    EGLWindow *window = getEGLWindow();

    // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
    // textures.
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);
    ANGLE_SKIP_TEST_IF(
        !IsEGLDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_colorspace"));
    // Possible GLES driver bug on Pixel2 devices: http://anglebug.com/42263865
    ANGLE_SKIP_TEST_IF(IsPixel2() && IsOpenGLES());

    GLubyte kLinearColor[] = {132, 55, 219, 255};
    GLubyte kSrgbColor[]   = {190, 128, 238, 255};

    // Switch to sRGB
    recreatePbufferInSrgbColorspace();
    EGLint colorspace = 0;
    eglQuerySurface(window->getDisplay(), mPbuffer, EGL_GL_COLORSPACE, &colorspace);
    EXPECT_EQ(colorspace, EGL_GL_COLORSPACE_SRGB_KHR);

    // Clear the Pbuffer surface with `kLinearColor`
    eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext());
    ASSERT_EGL_SUCCESS();

    glViewport(0, 0, static_cast<GLsizei>(mPbufferSize), static_cast<GLsizei>(mPbufferSize));
    glClearColor(kLinearColor[0] / 255.0f, kLinearColor[1] / 255.0f, kLinearColor[2] / 255.0f,
                 kLinearColor[3] / 255.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    // Expect glReadPixels to be `kSrgbColor` with a tolerance of 1
    EXPECT_PIXEL_NEAR(static_cast<GLint>(mPbufferSize) / 2, static_cast<GLint>(mPbufferSize) / 2,
                      kSrgbColor[0], kSrgbColor[1], kSrgbColor[2], kSrgbColor[3], 1);

    window->makeCurrent();

    // Create a texture and bind the Pbuffer to it
    GLuint texture = 0;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    EXPECT_GL_NO_ERROR();

    eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
    glViewport(0, 0, getWindowWidth(), getWindowHeight());
    ASSERT_EGL_SUCCESS();

    // Sample from a texture with `kSrgbColor` data and render into a surface in linear colorspace.
    glUseProgram(mTextureProgram);
    glUniform1i(mTextureUniformLocation, 0);

    drawQuad(mTextureProgram, "position", 0.5f);
    EXPECT_GL_NO_ERROR();

    // Unbind the texture
    eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
    ASSERT_EGL_SUCCESS();

    // Expect glReadPixels to be `kLinearColor` with a tolerance of 1
    EXPECT_PIXEL_NEAR(getWindowWidth() / 2, getWindowHeight() / 2, kLinearColor[0], kLinearColor[1],
                      kLinearColor[2], kLinearColor[3], 1);

    glDeleteTextures(1, &texture);
}

// Test clearing a Pbuffer in sRGB colorspace and checking the color is correct.
// Then bind the Pbuffer to a texture and verify it renders correctly.
// Then change texture state to skip decode and verify it renders correctly.
TEST_P(PbufferTest, ClearAndBindTexImageSrgbSkipDecode)
{
    EGLWindow *window = getEGLWindow();

    // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
    // textures.
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);
    ANGLE_SKIP_TEST_IF(
        !IsEGLDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_colorspace"));
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_sRGB_decode"));
    // Possible GLES driver bug on Pixel devices: http://anglebug.com/42263865
    ANGLE_SKIP_TEST_IF((IsPixel2() || IsPixel4()) && IsOpenGLES());

    GLubyte kLinearColor[] = {132, 55, 219, 255};
    GLubyte kSrgbColor[]   = {190, 128, 238, 255};

    // Switch to sRGB
    recreatePbufferInSrgbColorspace();
    EGLint colorspace = 0;
    eglQuerySurface(window->getDisplay(), mPbuffer, EGL_GL_COLORSPACE, &colorspace);
    EXPECT_EQ(colorspace, EGL_GL_COLORSPACE_SRGB_KHR);

    // Clear the Pbuffer surface with `kLinearColor`
    eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext());
    ASSERT_EGL_SUCCESS();

    glViewport(0, 0, static_cast<GLsizei>(mPbufferSize), static_cast<GLsizei>(mPbufferSize));
    glClearColor(kLinearColor[0] / 255.0f, kLinearColor[1] / 255.0f, kLinearColor[2] / 255.0f,
                 kLinearColor[3] / 255.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    // Expect glReadPixels to be `kSrgbColor` with a tolerance of 1
    EXPECT_PIXEL_NEAR(static_cast<GLint>(mPbufferSize) / 2, static_cast<GLint>(mPbufferSize) / 2,
                      kSrgbColor[0], kSrgbColor[1], kSrgbColor[2], kSrgbColor[3], 1);

    window->makeCurrent();

    // Create a texture and bind the Pbuffer to it
    GLuint texture = 0;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    EXPECT_GL_NO_ERROR();

    eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
    glViewport(0, 0, getWindowWidth(), getWindowHeight());
    ASSERT_EGL_SUCCESS();

    // Sample from a texture with `kSrgbColor` data and render into a surface in linear colorspace.
    glUseProgram(mTextureProgram);
    glUniform1i(mTextureUniformLocation, 0);

    drawQuad(mTextureProgram, "position", 0.5f);
    EXPECT_GL_NO_ERROR();

    // Expect glReadPixels to be `kLinearColor` with a tolerance of 1
    EXPECT_PIXEL_NEAR(getWindowWidth() / 2, getWindowHeight() / 2, kLinearColor[0], kLinearColor[1],
                      kLinearColor[2], kLinearColor[3], 1);

    // Set skip decode for the texture
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
    drawQuad(mTextureProgram, "position", 0.5f);

    // Texture is in skip decode mode, expect glReadPixels to be `kSrgbColor` with tolerance of 1
    EXPECT_PIXEL_NEAR(getWindowWidth() / 2, getWindowHeight() / 2, kSrgbColor[0], kSrgbColor[1],
                      kSrgbColor[2], kSrgbColor[3], 1);

    // Unbind the texture
    eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
    ASSERT_EGL_SUCCESS();

    glDeleteTextures(1, &texture);
}

// Verify that when eglBind/ReleaseTexImage are called, the texture images are freed and their
// size information is correctly updated.
TEST_P(PbufferTest, TextureSizeReset)
{
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers);
    ANGLE_SKIP_TEST_IF(!mSupportsBindTexImage);
    ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    EXPECT_GL_NO_ERROR();

    glUseProgram(mTextureProgram);
    glUniform1i(mTextureUniformLocation, 0);

    // Fill the texture with white pixels
    std::vector<GLColor> whitePixels(mPbufferSize * mPbufferSize, GLColor::white);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast<GLsizei>(mPbufferSize),
                 static_cast<GLsizei>(mPbufferSize), 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 whitePixels.data());
    EXPECT_GL_NO_ERROR();

    // Draw the white texture and verify that the pixels are correct
    drawQuad(mTextureProgram, "position", 0.5f);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);

    // Bind the EGL surface and draw with it, results are undefined since nothing has
    // been written to it
    EGLWindow *window = getEGLWindow();
    eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
    drawQuad(mTextureProgram, "position", 0.5f);
    EXPECT_GL_NO_ERROR();

    // Clear the back buffer to a unique color (green)
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    // Unbind the EGL surface and try to draw with the texture again, the texture's size should
    // now be zero and incomplete so the back buffer should be black
    eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
    drawQuad(mTextureProgram, "position", 0.5f);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
}

// Bind a Pbuffer, redefine the texture, and verify it renders correctly
TEST_P(PbufferTest, BindTexImageAndRedefineTexture)
{
    // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
    // textures.
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);

    EGLWindow *window = getEGLWindow();

    // Apply the Pbuffer and clear it to purple
    eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext());
    ASSERT_EGL_SUCCESS();

    glViewport(0, 0, static_cast<GLsizei>(mPbufferSize), static_cast<GLsizei>(mPbufferSize));
    glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_EQ(static_cast<GLint>(mPbufferSize) / 2, static_cast<GLint>(mPbufferSize) / 2, 255,
                    0, 255, 255);

    // Apply the window surface
    window->makeCurrent();

    // Create a texture and bind the Pbuffer to it
    GLuint texture = 0;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    EXPECT_GL_NO_ERROR();

    eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
    glViewport(0, 0, getWindowWidth(), getWindowHeight());
    ASSERT_EGL_SUCCESS();

    // Redefine the texture
    unsigned int pixelValue = 0xFFFF00FF;
    std::vector<unsigned int> pixelData(getWindowWidth() * getWindowHeight(), pixelValue);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, &pixelData[0]);

    // Draw a quad and verify that it is magenta
    glUseProgram(mTextureProgram);
    glUniform1i(mTextureUniformLocation, 0);

    drawQuad(mTextureProgram, "position", 0.5f);
    EXPECT_GL_NO_ERROR();

    // Verify that magenta was drawn
    EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 255, 255);

    glDeleteTextures(1, &texture);
}

// Bind a Pbuffer, generate mipmap for it, and verify it renders correctly
TEST_P(PbufferTest, BindTexImageAndGenerateMipmap)
{
    // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
    // textures.
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);
    // Crash in drawQuad. http://anglebug.com/412867392
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);

    EGLWindow *window = getEGLWindow();

    EGLSurface pbuffer;
    GLuint texture = 0;

    static EGLint pbufferAttributes[] = {
        EGL_WIDTH,          2,
        EGL_HEIGHT,         1,
        EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
        EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
        EGL_MIPMAP_TEXTURE, GL_TRUE,
        EGL_NONE,
    };

    pbuffer = eglCreatePbufferSurface(window->getDisplay(), window->getConfig(), pbufferAttributes);
    ASSERT_EGL_SUCCESS();

    ASSERT_NE(EGL_NO_SURFACE, pbuffer);

    // create texture
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
    EXPECT_GL_NO_ERROR();

    // bind pbuffer as texture storage
    eglBindTexImage(window->getDisplay(), pbuffer, EGL_BACK_BUFFER);
    ASSERT_EGL_SUCCESS();
    EXPECT_GL_NO_ERROR();

    unsigned int pixelValue = 0xFFFF00FF;
    std::vector<unsigned int> pixelData(2, pixelValue);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixelData[0]);
    glGenerateMipmap(GL_TEXTURE_2D);

    glViewport(0, 0, 1, 1);
    // Draw a quad and verify that it is magenta
    glUseProgram(mTextureProgram);
    glUniform1i(mTextureUniformLocation, 0);

    drawQuad(mTextureProgram, "position", 0.5f);
    EXPECT_GL_NO_ERROR();

    // Verify that magenta was drawn
    EXPECT_PIXEL_EQ(0, 0, 255, 0, 255, 255);

    EXPECT_TRUE(eglMakeCurrent(window->getDisplay(), pbuffer, pbuffer, window->getContext()));
    ASSERT_EGL_SUCCESS();
    glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    // Verify that yellow was drawn to pbuffer
    EXPECT_PIXEL_EQ(0, 0, 255, 255, 0, 255);

    drawQuad(mTextureProgram, "position", 0.5f);
    EXPECT_GL_NO_ERROR();

    // Verify that the texture color is still magenta (texture is disconnected from pbuffer)
    EXPECT_PIXEL_EQ(0, 0, 255, 0, 255, 255);

    glDeleteTextures(1, &texture);
    window->makeCurrent();
    eglDestroySurface(window->getDisplay(), pbuffer);
}

// Bind the Pbuffer to a texture, use that texture as Framebuffer color attachment and then
// destroy framebuffer, texture and Pbuffer.
TEST_P(PbufferTest, UseAsFramebufferColorThenDestroy)
{
    // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
    // textures.
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);

    EGLWindow *window = getEGLWindow();

    // Apply the window surface
    window->makeCurrent();

    // Create a texture and bind the Pbuffer to it
    GLuint texture = 0;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    EXPECT_GL_NO_ERROR();

    eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
    ASSERT_EGL_SUCCESS();

    // Create Framebuffer and use texture as color attachment
    GLuint fbo;
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    ANGLE_SKIP_TEST_IF(status == GL_FRAMEBUFFER_UNSUPPORTED);
    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
    glDisable(GL_DEPTH_TEST);
    glViewport(0, 0, static_cast<GLsizei>(mPbufferSize), static_cast<GLsizei>(mPbufferSize));
    ASSERT_GL_NO_ERROR();

    // Draw a quad in order to open a RenderPass
    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    glUseProgram(redProgram);
    ASSERT_GL_NO_ERROR();

    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Unbind resources
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
    glViewport(0, 0, getWindowWidth(), getWindowHeight());
    ASSERT_GL_NO_ERROR();

    // Delete resources
    glDeleteFramebuffers(1, &fbo);
    glDeleteTextures(1, &texture);
    ASSERT_GL_NO_ERROR();

    // Destroy Pbuffer
    destroyPbuffer();

    // Finish work
    glFinish();
    ASSERT_GL_NO_ERROR();
}

// Bind the Pbuffer to a texture, use that texture as Framebuffer color attachment and then
// destroy framebuffer, texture and Pbuffer. A bound but released TexImages are destroyed
// only when the binding is overwritten.
TEST_P(PbufferTest, UseAsFramebufferColorThenDeferredDestroy)
{
    // Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
    // textures.
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);
    EGLWindow *window = getEGLWindow();
    window->makeCurrent();

    // Create a texture and bind the Pbuffer to it
    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    EXPECT_GL_NO_ERROR();

    EGLSurface otherPbuffer = createTestPbufferSurface();
    ASSERT_EGL_SUCCESS();
    ASSERT_NE(otherPbuffer, EGL_NO_SURFACE);

    eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
    ASSERT_EGL_SUCCESS();
    eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
    ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
    eglBindTexImage(window->getDisplay(), otherPbuffer, EGL_BACK_BUFFER);
    ASSERT_EGL_SUCCESS();
    eglReleaseTexImage(window->getDisplay(), otherPbuffer, EGL_BACK_BUFFER);
    ASSERT_EGL_SUCCESS();
    eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
    ASSERT_EGL_SUCCESS();
    eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
    ASSERT_EGL_SUCCESS();

    destroyPbuffer();
    destroyTestPbufferSurface(otherPbuffer);
    ASSERT_EGL_SUCCESS();

    // Finish work
    glFinish();
    ASSERT_GL_NO_ERROR();
}

// Test the validation errors for bad parameters for eglCreatePbufferSurface
TEST_P(PbufferTest, NegativeValidationBadAttributes)
{
    EGLWindow *window = getEGLWindow();
    EGLSurface pbufferSurface;

    const EGLint invalidPBufferAttributeList[][3] = {
        {EGL_MIPMAP_TEXTURE, EGL_MIPMAP_TEXTURE, EGL_NONE},
        {EGL_LARGEST_PBUFFER, EGL_LARGEST_PBUFFER, EGL_NONE},
    };

    for (size_t i = 0; i < 2; i++)
    {
        pbufferSurface = eglCreatePbufferSurface(window->getDisplay(), window->getConfig(),
                                                 &invalidPBufferAttributeList[i][0]);
        ASSERT_EQ(pbufferSurface, EGL_NO_SURFACE);
        ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
    }
}

// Test that passing colorspace attributes do not generate EGL validation errors
// when EGL_ANGLE_colorspace_attribute_passthrough extension is supported.
TEST_P(PbufferColorspaceTest, CreateSurfaceWithColorspace)
{
    EGLDisplay dpy = getEGLWindow()->getDisplay();
    const bool extensionSupported =
        IsEGLDisplayExtensionEnabled(dpy, "EGL_EXT_gl_colorspace_display_p3_passthrough");
    const bool passthroughExtensionSupported =
        IsEGLDisplayExtensionEnabled(dpy, "EGL_ANGLE_colorspace_attribute_passthrough");

    EGLSurface pbufferSurface        = EGL_NO_SURFACE;
    const EGLint pBufferAttributes[] = {
        EGL_WIDTH,         static_cast<EGLint>(mPbufferSize),
        EGL_HEIGHT,        static_cast<EGLint>(mPbufferSize),
        EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT,
        EGL_NONE,          EGL_NONE,
    };

    pbufferSurface = eglCreatePbufferSurface(dpy, getEGLWindow()->getConfig(), pBufferAttributes);
    if (extensionSupported)
    {
        // If EGL_EXT_gl_colorspace_display_p3_passthrough is supported
        // "pbufferSurface" should be a valid pbuffer surface.
        ASSERT_NE(pbufferSurface, EGL_NO_SURFACE);
        ASSERT_EGL_SUCCESS();
    }
    else if (!extensionSupported && passthroughExtensionSupported)
    {
        // If EGL_ANGLE_colorspace_attribute_passthrough was the only extension supported
        // we should not expect a validation error.
        ASSERT_NE(eglGetError(), EGL_BAD_ATTRIBUTE);
    }
    else
    {
        // Otherwise we should expect an EGL_BAD_ATTRIBUTE validation error.
        ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
    }

    // Cleanup
    if (pbufferSurface != EGL_NO_SURFACE)
    {
        eglDestroySurface(dpy, pbufferSurface);
    }
}

// Test the implementation for EGL_LARGEST_PBUFFER
TEST_P(PbufferTest, LargestPbuffer)
{
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers);
    ANGLE_SKIP_TEST_IF(!IsARM());
    EGLWindow *window  = getEGLWindow();
    EGLDisplay display = window->getDisplay();
    EGLSurface pbufferSurface;

    EGLint maxPbufferWidth;
    EGLint maxPbufferHeight;
    EGLint value;
    EGLint pBufferAttributes[] = {EGL_WIDTH,           1,         EGL_HEIGHT, 1,
                                  EGL_LARGEST_PBUFFER, EGL_FALSE, EGL_NONE};

    // Check that eglCreatePbufferSurface can succeed when EGL_LARGEST_PBUFFER is set to EGL_FALSE
    pbufferSurface = eglCreatePbufferSurface(display, window->getConfig(), pBufferAttributes);
    ASSERT_NE(pbufferSurface, EGL_NO_SURFACE);
    ASSERT_EGL_SUCCESS();

    // Cleanup
    eglDestroySurface(display, pbufferSurface);

    EXPECT_EGL_TRUE(
        eglGetConfigAttrib(display, window->getConfig(), EGL_MAX_PBUFFER_WIDTH, &maxPbufferWidth));
    pBufferAttributes[1] = maxPbufferWidth + 1;
    pBufferAttributes[5] = EGL_TRUE;

    // Check that eglCreatePbufferSurface clamps an EGL_WIDTH that is too large with
    // EGL_LARGEST_PBUFFER set
    pbufferSurface = eglCreatePbufferSurface(display, window->getConfig(), pBufferAttributes);
    ASSERT_NE(pbufferSurface, EGL_NO_SURFACE);
    ASSERT_EGL_SUCCESS();

    EXPECT_EGL_TRUE(eglQuerySurface(display, pbufferSurface, EGL_WIDTH, &value));
    ASSERT_EGL_SUCCESS();
    ASSERT_EQ(value, maxPbufferWidth);

    // Cleanup
    eglDestroySurface(display, pbufferSurface);

    pBufferAttributes[1] = 1;

    EXPECT_EGL_TRUE(eglGetConfigAttrib(display, window->getConfig(), EGL_MAX_PBUFFER_HEIGHT,
                                       &maxPbufferHeight));
    pBufferAttributes[3] = maxPbufferHeight + 1;

    // Check that eglCreatePbufferSurface clamps an EGL_HEIGHT that is too large with
    // EGL_LARGEST_PBUFFER set
    pbufferSurface = eglCreatePbufferSurface(display, window->getConfig(), pBufferAttributes);
    ASSERT_NE(pbufferSurface, EGL_NO_SURFACE);
    ASSERT_EGL_SUCCESS();

    EXPECT_EGL_TRUE(eglQuerySurface(display, pbufferSurface, EGL_HEIGHT, &value));
    ASSERT_EGL_SUCCESS();
    ASSERT_EQ(value, maxPbufferHeight);

    // Cleanup
    eglDestroySurface(display, pbufferSurface);
}

// Test the implementation for query format sizes from zero sized pbuffer surface
TEST_P(PbufferTest, ZeroSizedSurfaceFormatQuery)
{
    ANGLE_SKIP_TEST_IF(!mSupportsPbuffers);
    EGLWindow *window  = getEGLWindow();
    EGLDisplay display = window->getDisplay();
    EGLSurface pbufferSurface;

    EGLint pBufferAttributes[] = {EGL_WIDTH, 0, EGL_HEIGHT, 0, EGL_NONE};

    pbufferSurface = eglCreatePbufferSurface(display, window->getConfig(), pBufferAttributes);
    ASSERT_NE(pbufferSurface, EGL_NO_SURFACE);
    ASSERT_EGL_SUCCESS();

    EGLint width, height;
    EXPECT_EGL_TRUE(eglQuerySurface(display, pbufferSurface, EGL_WIDTH, &width));
    EXPECT_EGL_TRUE(eglQuerySurface(display, pbufferSurface, EGL_HEIGHT, &height));
    EXPECT_EQ(width, 0);
    EXPECT_EQ(height, 0);

    window->makeCurrent(pbufferSurface, pbufferSurface, window->getContext());

    GLint redBits, greenBits, blueBits, alphaBits;
    glGetIntegerv(GL_RED_BITS, &redBits);
    glGetIntegerv(GL_GREEN_BITS, &greenBits);
    glGetIntegerv(GL_BLUE_BITS, &blueBits);
    glGetIntegerv(GL_ALPHA_BITS, &alphaBits);
    ASSERT_GL_NO_ERROR();
    EXPECT_EQ(redBits, 8);
    EXPECT_EQ(greenBits, 8);
    EXPECT_EQ(blueBits, 8);
    EXPECT_EQ(alphaBits, 8);

    // Cleanup
    window->makeCurrent();
    eglDestroySurface(display, pbufferSurface);
}

ANGLE_INSTANTIATE_TEST_ES2(PbufferTest);

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PbufferColorspaceTest);
ANGLE_INSTANTIATE_TEST_ES3_AND(PbufferColorspaceTest,
                               ES3_VULKAN().enable(Feature::EglColorspaceAttributePassthrough));
