//
// 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.
//
// ImageTest:
//   Tests the correctness of eglImage.
//

#ifdef UNSAFE_BUFFERS_BUILD
#    pragma allow_unsafe_buffers
#endif

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

#if defined(ANGLE_ENABLE_WGPU)
#    include <dawn/native/DawnNative.h>
#    include <webgpu/webgpu.h>
#endif

#include "common/android_util.h"

#if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 29
#    define ANGLE_AHARDWARE_BUFFER_SUPPORT
// NDK header file for access to Android Hardware Buffers
#    include <android/hardware_buffer.h>
#    define ANGLE_AHARDWARE_BUFFER_LOCK_PLANES_SUPPORT
#endif

#if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 33
constexpr bool kHasAHBFrontBufferUsageSupport = 1;
#else
[[maybe_unused]] constexpr bool kHasAHBFrontBufferUsageSupport = 0;
#endif

namespace angle
{
namespace
{
constexpr char kOESExt[]                         = "GL_OES_EGL_image";
constexpr char kExternalExt[]                    = "GL_OES_EGL_image_external";
constexpr char kExternalESSL3Ext[]               = "GL_OES_EGL_image_external_essl3";
constexpr char kYUVInternalFormatExt[]           = "GL_ANGLE_yuv_internal_format";
constexpr char kYUVTargetExt[]                   = "GL_EXT_YUV_target";
constexpr char kRGBXInternalFormatExt[]          = "GL_ANGLE_rgbx_internal_format";
constexpr char kBaseExt[]                        = "EGL_KHR_image_base";
constexpr char k2DTextureExt[]                   = "EGL_KHR_gl_texture_2D_image";
constexpr char k3DTextureExt[]                   = "EGL_KHR_gl_texture_3D_image";
constexpr char kPixmapExt[]                      = "EGL_KHR_image_pixmap";
constexpr char kRenderbufferExt[]                = "EGL_KHR_gl_renderbuffer_image";
constexpr char kCubemapExt[]                     = "EGL_KHR_gl_texture_cubemap_image";
constexpr char kImageGLColorspaceExt[]           = "EGL_EXT_image_gl_colorspace";
constexpr char kEGLImageArrayExt[]               = "GL_EXT_EGL_image_array";
constexpr char kEGLAndroidImageNativeBufferExt[] = "EGL_ANDROID_image_native_buffer";
constexpr char kEGLImageStorageExt[]             = "GL_EXT_EGL_image_storage";
constexpr char kEGLImageStorageCompressionExt[]  = "GL_EXT_EGL_image_storage_compression";
constexpr char kTextureStorageCompressionExt[]   = "GL_EXT_texture_storage_compression";
constexpr char kWebGPUDeviceExt[]                = "EGL_ANGLE_device_webgpu";
constexpr char kWebGPUTextureExt[]               = "EGL_ANGLE_webgpu_texture_client_buffer";
constexpr EGLint kDefaultAttribs[]               = {
    EGL_IMAGE_PRESERVED,
    EGL_TRUE,
    EGL_NONE,
};
constexpr EGLint kColorspaceAttribs[] = {
    EGL_IMAGE_PRESERVED, EGL_TRUE, EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_SRGB_KHR, EGL_NONE,
};
constexpr EGLint kNativeClientBufferAttribs_RGBA8_Texture[] = {
    EGL_WIDTH,
    1,
    EGL_HEIGHT,
    1,
    EGL_RED_SIZE,
    8,
    EGL_GREEN_SIZE,
    8,
    EGL_BLUE_SIZE,
    8,
    EGL_ALPHA_SIZE,
    8,
    EGL_NATIVE_BUFFER_USAGE_ANDROID,
    EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID,
    EGL_NONE};
constexpr EGLint kNativeClientBufferAttribs_RGBA8_Renderbuffer[] = {
    EGL_WIDTH,
    1,
    EGL_HEIGHT,
    1,
    EGL_RED_SIZE,
    8,
    EGL_GREEN_SIZE,
    8,
    EGL_BLUE_SIZE,
    8,
    EGL_ALPHA_SIZE,
    8,
    EGL_NATIVE_BUFFER_USAGE_ANDROID,
    EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID,
    EGL_NONE};
// Color data in linear and sRGB colorspace
// 2D texture data
GLubyte kLinearColor[] = {132, 55, 219, 255};
GLubyte kSrgbColor[]   = {190, 128, 238, 255};
// 3D texture data
GLubyte kLinearColor3D[] = {131, 242, 100, 255, 201, 89, 133, 255};
GLubyte kSrgbColor3D[]   = {190, 249, 168, 255, 230, 159, 191, 255};
// Cubemap texture data
GLubyte kLinearColorCube[] = {75, 135, 205, 255, 201, 89,  133, 255, 111, 201, 108, 255,
                              30, 90,  230, 255, 180, 210, 70,  255, 77,  111, 99,  255};
GLubyte kSrgbColorCube[]   = {148, 192, 232, 255, 230, 159, 191, 255, 176, 230, 174, 255,
                              96,  160, 244, 255, 219, 234, 143, 255, 149, 176, 167, 255};
GLfloat kCubeFaceX[]       = {1.0, -1.0, 0.0, 0.0, 0.0, 0.0};
GLfloat kCubeFaceY[]       = {0.0, 0.0, 1.0, -1.0, 0.0, 0.0};
GLfloat kCubeFaceZ[]       = {0.0, 0.0, 0.0, 0.0, 1.0, -1.0};
// YUV texture data - ensure they are narrow range compatible values
GLubyte kYUVColorBlackY[]   = {16, 16, 16, 16};
GLubyte kYUVColorBlackCb[]  = {128};
GLubyte kYUVColorBlackCr[]  = {128};
GLubyte kYUVColorPurpleY[]  = {125, 125, 125, 125};
GLubyte kYUVColorPurpleCb[] = {193};
GLubyte kYUVColorPurpleCr[] = {174};
GLubyte kYUVColorRedY[]     = {81, 81, 81, 81};
GLubyte kYUVColorRedCb[]    = {90};
GLubyte kYUVColorRedCr[]    = {240};

constexpr int kColorspaceAttributeIndex     = 2;
constexpr int k3DColorspaceAttributeIndex   = 4;
constexpr int kTextureZOffsetAttributeIndex = 1;
constexpr size_t kCubeFaceCount             = 6;

constexpr int AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM  = 1;
constexpr int AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM  = 2;
constexpr int AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM    = 3;
constexpr int AHARDWAREBUFFER_FORMAT_D24_UNORM       = 0x31;
constexpr int AHARDWAREBUFFER_FORMAT_Y8Cr8Cb8_420_SP = 0x11;
constexpr int AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420    = 0x23;
constexpr int AHARDWAREBUFFER_FORMAT_YCbCr_P210      = 0x3c;
constexpr int AHARDWAREBUFFER_FORMAT_YV12            = 0x32315659;

[[maybe_unused]] constexpr uint64_t ANGLE_AHARDWAREBUFFER_USAGE_FRONT_BUFFER = (1ULL << 32);

}  // anonymous namespace

class ImageTest : public ANGLETest<>
{
  protected:
    ImageTest()
    {
        setWindowWidth(128);
        setWindowHeight(128);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
        setConfigDepthBits(24);
    }

    const char *getVS() const
    {
        return 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;
})";
    }

    const char *getVS2DArray() const
    {
        return R"(#version 300 es
out vec2 texcoord;
in vec4 position;
void main()
{
    gl_Position = vec4(position.xy, 0.0, 1.0);
    texcoord = (position.xy * 0.5) + 0.5;
})";
    }

    const char *getVS3D() const
    {
        return R"(#version 300 es
out vec2 texcoord;
in vec4 position;

void main()
{
    gl_Position = vec4(position.xy, 0.0, 1.0);
    texcoord = (position.xy * 0.5) + 0.5;
})";
    }

    const char *getVSCube() const
    {
        return R"(#version 300 es
in vec4 position;
void main()
{
    gl_Position = vec4(position.xy, 0.0, 1.0);
})";
    }

    const char *getVSCubeArray() const
    {
        return R"(#version 310 es
in vec4 position;
void main()
{
    gl_Position = vec4(position.xy, 0.0, 1.0);
})";
    }

    const char *getVSESSL3() const
    {
        return R"(#version 300 es
precision highp float;
in vec4 position;
out vec2 texcoord;

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

    const char *getTextureFS() const
    {
        return R"(precision highp float;
uniform sampler2D tex;
varying vec2 texcoord;

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

    const char *getTexture2DArrayFS() const
    {
        return R"(#version 300 es
precision highp float;
uniform highp sampler2DArray tex2DArray;
uniform uint layer;
in vec2 texcoord;
out vec4 fragColor;
void main()
{
    fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, float(layer)));
})";
    }

    const char *getTexture3DFS() const
    {
        return R"(#version 300 es
precision highp float;
uniform highp sampler3D tex3D;
uniform float layer;
in vec2 texcoord;
out vec4 fragColor;
void main()
{
    fragColor = texture(tex3D, vec3(texcoord.x, texcoord.y, layer));
})";
    }

    const char *getTextureCubeFS() const
    {
        return R"(#version 300 es
precision highp float;
uniform highp samplerCube texCube;
uniform vec3 faceCoord;
out vec4 fragColor;
void main()
{
    fragColor = texture(texCube, faceCoord);
})";
    }

    const char *getTextureCubeArrayFS() const
    {
        return R"(#version 310 es
#extension GL_OES_texture_cube_map_array : require
precision highp float;
uniform highp samplerCubeArray texCubeArray;
uniform vec3 faceCoord;
uniform uint layer;
out vec4 fragColor;
void main()
{
    fragColor = texture(texCubeArray, vec4(faceCoord, float(layer)));
})";
    }

    const char *getTextureExternalFS() const
    {
        return R"(#extension GL_OES_EGL_image_external : require
precision highp float;
uniform samplerExternalOES tex;
varying vec2 texcoord;

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

    const char *getTextureExternalESSL3FS() const
    {
        return R"(#version 300 es
#extension GL_OES_EGL_image_external_essl3 : require
precision highp float;
uniform samplerExternalOES tex;
in vec2 texcoord;
out vec4 color;

void main()
{
    color = texture(tex, texcoord);
})";
    }

    const char *getTextureYUVVS() const
    {
        return R"(#version 300 es
#extension GL_EXT_YUV_target : require
precision highp float;
uniform __samplerExternal2DY2YEXT tex;
in vec4 position;
out vec4 color;

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

    const char *getFetchYUVVS() const
    {
        return R"(#version 300 es
#extension GL_OES_EGL_image_external_essl3 : enable
precision highp float;
uniform samplerExternalOES tex;
in vec4 position;
out vec4 color;

void main()
{
    gl_Position = position;
    vec2 texcoord = (position.xy * 0.5) + 0.5;
    texcoord.y = 1.0 - texcoord.y;
    ivec2 fetchcoord = ivec2(texcoord * vec2(textureSize(tex, 0)));
    fetchcoord = min(fetchcoord, textureSize(tex, 0) - ivec2(1.0));
    color = texelFetch(tex, fetchcoord, 0);
})";
    }

    const char *getPassThroughFS() const
    {
        return R"(#version 300 es
precision highp float;
in vec4 color;
out vec4 frag_color;

void main()
{
    frag_color = color;
})";
    }

    const char *getTextureYUVFS() const
    {
        return R"(#version 300 es
#extension GL_EXT_YUV_target : require
precision highp float;
uniform __samplerExternal2DY2YEXT tex;
in vec2 texcoord;
out vec4 color;

void main()
{
    color = texture(tex, texcoord);
})";
    }

    const char *getFetchYUVFS() const
    {
        return R"(#version 300 es
#extension GL_OES_EGL_image_external_essl3 : enable
precision highp float;
uniform samplerExternalOES tex;
in vec2 texcoord;
out vec4 color;

void main()
{
    ivec2 fetchcoord = ivec2(texcoord * vec2(textureSize(tex, 0)));
    fetchcoord = min(fetchcoord, textureSize(tex, 0) - ivec2(1.0));
    color = texelFetch(tex, fetchcoord, 0);
})";
    }

    const char *getRenderYUVFS() const
    {
        return R"(#version 300 es
#extension GL_EXT_YUV_target : require
precision highp float;
uniform vec4 u_color;
layout (yuv) out vec4 color;

void main()
{
    color = u_color;
})";
    }

    // Same as getRenderYUVFS(), but with the yuv layout specified multiple times, which should not
    // make a difference.  Some tests use this shader instead of getRenderYUVFS() just to exercise
    // compiling such a shader.
    const char *getRenderYUV2FS() const
    {
        return R"(#version 300 es
#extension GL_EXT_YUV_target : require
precision highp float;
uniform vec4 u_color;
layout (yuv, yuv, yuv) out vec4 color;

void main()
{
    color = u_color;
})";
    }

    void testSetUp() override
    {
        mTextureProgram = CompileProgram(getVS(), getTextureFS());
        if (mTextureProgram == 0)
        {
            FAIL() << "shader compilation failed.";
        }

        mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");

        if (getClientMajorVersion() >= 3)
        {
            m2DArrayTextureProgram = CompileProgram(getVS2DArray(), getTexture2DArrayFS());
            if (m2DArrayTextureProgram == 0)
            {
                FAIL() << "shader compilation failed.";
            }

            m2DArrayTextureUniformLocation =
                glGetUniformLocation(m2DArrayTextureProgram, "tex2DArray");
            m2DArrayTextureLayerUniformLocation =
                glGetUniformLocation(m2DArrayTextureProgram, "layer");
        }

        if (getClientMajorVersion() >= 3)
        {
            m3DTextureProgram = CompileProgram(getVS3D(), getTexture3DFS());
            if (m3DTextureProgram == 0)
            {
                FAIL() << "shader compilation failed.";
            }

            m3DTextureUniformLocation      = glGetUniformLocation(m3DTextureProgram, "tex3D");
            m3DTextureLayerUniformLocation = glGetUniformLocation(m3DTextureProgram, "layer");
        }

        if (IsGLExtensionEnabled("GL_OES_EGL_image_external"))
        {
            mTextureExternalProgram = CompileProgram(getVS(), getTextureExternalFS());
            ASSERT_NE(0u, mTextureExternalProgram) << "shader compilation failed.";

            mTextureExternalUniformLocation = glGetUniformLocation(mTextureExternalProgram, "tex");
        }

        if (IsGLExtensionEnabled("GL_OES_EGL_image_external_essl3"))
        {
            mTextureExternalESSL3Program =
                CompileProgram(getVSESSL3(), getTextureExternalESSL3FS());
            ASSERT_NE(0u, mTextureExternalESSL3Program) << "shader compilation failed.";

            mTextureExternalESSL3UniformLocation =
                glGetUniformLocation(mTextureExternalESSL3Program, "tex");
        }

        if (IsGLExtensionEnabled(kYUVTargetExt))
        {
            mTextureYUVProgram = CompileProgram(getVSESSL3(), getTextureYUVFS());
            ASSERT_NE(0u, mTextureYUVProgram) << "shader compilation failed.";

            mTextureYUVUniformLocation = glGetUniformLocation(mTextureYUVProgram, "tex");

            mTextureYUVVSProgram = CompileProgram(getTextureYUVVS(), getPassThroughFS());
            ASSERT_NE(0u, mTextureYUVVSProgram) << "shader compilation failed.";

            mTextureYUVVSUniformLocation = glGetUniformLocation(mTextureYUVVSProgram, "tex");

            mRenderYUVProgram = CompileProgram(getVSESSL3(), getRenderYUVFS());
            ASSERT_NE(0u, mRenderYUVProgram) << "shader compilation failed.";

            mRenderYUVUniformLocation = glGetUniformLocation(mRenderYUVProgram, "u_color");

            mRenderYUVProgram2 = CompileProgram(getVSESSL3(), getRenderYUV2FS());
            ASSERT_NE(0u, mRenderYUVProgram2) << "shader compilation failed.";

            mRenderYUVUniformLocation = glGetUniformLocation(mRenderYUVProgram2, "u_color");
        }

        if (IsGLExtensionEnabled(kExternalESSL3Ext))
        {
            mFetchYUVProgram = CompileProgram(getVSESSL3(), getFetchYUVFS());
            ASSERT_NE(0u, mFetchYUVProgram) << "shader compilation failed.";

            mFetchYUVUniformLocation = glGetUniformLocation(mFetchYUVProgram, "tex");

            mFetchYUVVSProgram = CompileProgram(getFetchYUVVS(), getPassThroughFS());
            ASSERT_NE(0u, mFetchYUVVSProgram) << "shader compilation failed.";

            mFetchYUVVSUniformLocation = glGetUniformLocation(mFetchYUVVSProgram, "tex");
        }

        if (IsGLExtensionEnabled(kEGLImageStorageExt))
        {
            mCubeTextureProgram = CompileProgram(getVSCube(), getTextureCubeFS());
            if (mCubeTextureProgram == 0)
            {
                FAIL() << "shader compilation failed.";
            }
            mCubeTextureUniformLocation = glGetUniformLocation(mCubeTextureProgram, "texCube");
            mCubeTextureFaceCoordUniformLocation =
                glGetUniformLocation(mCubeTextureProgram, "faceCoord");

            if ((getClientMajorVersion() >= 3 && getClientMinorVersion() >= 1) &&
                IsGLExtensionEnabled("GL_EXT_texture_cube_map_array"))
            {
                mCubeArrayTextureProgram =
                    CompileProgram(getVSCubeArray(), getTextureCubeArrayFS());
                if (mCubeArrayTextureProgram == 0)
                {
                    FAIL() << "shader compilation failed.";
                }
                mCubeArrayTextureUniformLocation =
                    glGetUniformLocation(mCubeArrayTextureProgram, "texCubeArray");
                mCubeArrayTextureFaceCoordUniformLocation =
                    glGetUniformLocation(mCubeArrayTextureProgram, "faceCoord");
                mCubeArrayTextureLayerUniformLocation =
                    glGetUniformLocation(mCubeArrayTextureProgram, "layer");
            }
        }

        ASSERT_GL_NO_ERROR();
    }

    void testTearDown() override
    {
        glDeleteProgram(mTextureProgram);
        glDeleteProgram(mTextureExternalProgram);
        glDeleteProgram(mTextureExternalESSL3Program);
        glClearColor(0, 0, 0, 0);
        glClear(GL_COLOR_BUFFER_BIT);

        ASSERT_GL_NO_ERROR();
    }

    // 1) For tests that sample from EGLImages with colorspace override -
    //    1) Always upload color values in sRGB colorspace
    //    2) The image should be treated as if it was an sRGB image resulting in
    //       the sampled value to be to decoded to linear colorspace
    //
    // 2) For tests that render to EGLImages with colorspace override -
    //    1) Always upload color values in linear colorspace
    //    2) The image should be treated as if it was an sRGB image resulting in
    //       the rendered color to be encoded in sRGB colorspace

    enum class EglImageUsage
    {
        Sampling,
        Rendering
    };

    bool attribListHasSrgbColorspace(const EGLint *attribs,
                                     const int colorspaceAttributeIndex) const
    {
        return (attribs[colorspaceAttributeIndex] == EGL_GL_COLORSPACE &&
                attribs[colorspaceAttributeIndex + 1] == EGL_GL_COLORSPACE_SRGB_KHR);
    }

    GLubyte *getExpected2DColorForAttribList(const EGLint *attribs,
                                             EglImageUsage usage = EglImageUsage::Sampling) const
    {
        const bool srgbColorspace = attribListHasSrgbColorspace(attribs, kColorspaceAttributeIndex);
        return (usage == EglImageUsage::Sampling) ? (srgbColorspace ? kLinearColor : kSrgbColor)
                                                  : (srgbColorspace ? kSrgbColor : kLinearColor);
    }

    GLubyte *getExpected3DColorForAttribList(const EGLint *attribs,
                                             EglImageUsage usage = EglImageUsage::Sampling) const
    {
        const bool srgbColorspace =
            attribListHasSrgbColorspace(attribs, k3DColorspaceAttributeIndex);
        return (usage == EglImageUsage::Sampling)
                   ? (srgbColorspace ? kLinearColor3D : kSrgbColor3D)
                   : (srgbColorspace ? kSrgbColor3D : kLinearColor3D);
    }

    GLubyte *getExpectedCubeColorForAttribList(const EGLint *attribs,
                                               EglImageUsage usage = EglImageUsage::Sampling) const
    {
        const bool srgbColorspace = attribListHasSrgbColorspace(attribs, kColorspaceAttributeIndex);
        return (usage == EglImageUsage::Sampling)
                   ? (srgbColorspace ? kLinearColorCube : kSrgbColorCube)
                   : (srgbColorspace ? kSrgbColorCube : kLinearColorCube);
    }

    void createEGLImage2DTextureStorage(size_t width,
                                        size_t height,
                                        GLenum format,
                                        const GLint *attribs,
                                        GLTexture &sourceTexture,
                                        EGLImageKHR *outSourceImage)
    {

        glBindTexture(GL_TEXTURE_2D, sourceTexture);
        glTexStorageAttribs2DEXT(GL_TEXTURE_2D, 1, format, static_cast<GLsizei>(width),
                                 static_cast<GLsizei>(height), attribs);

        ASSERT_GL_NO_ERROR();
        // Disable mipmapping
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        ASSERT_GL_NO_ERROR();

        // Create an image from the source texture
        EGLWindow *window = getEGLWindow();

        EGLImageKHR image =
            eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
                              reinterpretHelper<EGLClientBuffer>(sourceTexture), nullptr);

        ASSERT_EGL_SUCCESS();

        *outSourceImage = image;
    }

    void createEGLImage2DTextureSource(size_t width,
                                       size_t height,
                                       GLenum format,
                                       GLenum type,
                                       const EGLint *attribs,
                                       const void *data,
                                       GLTexture &sourceTexture,
                                       EGLImageKHR *outSourceImage)
    {
        // Create a source 2D texture
        glBindTexture(GL_TEXTURE_2D, sourceTexture);

        glTexImage2D(GL_TEXTURE_2D, 0, format, static_cast<GLsizei>(width),
                     static_cast<GLsizei>(height), 0, format, type, data);

        // Disable mipmapping
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        ASSERT_GL_NO_ERROR();

        // Create an image from the source texture
        EGLWindow *window = getEGLWindow();

        EGLImageKHR image =
            eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
                              reinterpretHelper<EGLClientBuffer>(sourceTexture), attribs);

        ASSERT_EGL_SUCCESS();

        *outSourceImage = image;
    }

    void createEGLImageCubemapTextureSource(size_t width,
                                            size_t height,
                                            GLenum format,
                                            GLenum type,
                                            const EGLint *attribs,
                                            const uint8_t *data,
                                            size_t dataStride,
                                            EGLenum imageTarget,
                                            GLTexture &sourceTexture,
                                            EGLImageKHR *outSourceImage)
    {
        // Create a source cube map texture
        glBindTexture(GL_TEXTURE_CUBE_MAP, sourceTexture);

        for (GLenum faceIdx = 0; faceIdx < 6; faceIdx++)
        {
            glTexImage2D(faceIdx + GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format,
                         static_cast<GLsizei>(width), static_cast<GLsizei>(height), 0, format, type,
                         data + (faceIdx * dataStride));
        }

        // Disable mipmapping
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        ASSERT_GL_NO_ERROR();

        // Create an image from the source texture
        EGLWindow *window = getEGLWindow();

        EGLImageKHR image =
            eglCreateImageKHR(window->getDisplay(), window->getContext(), imageTarget,
                              reinterpretHelper<EGLClientBuffer>(sourceTexture), attribs);

        ASSERT_EGL_SUCCESS();

        *outSourceImage = image;
    }

    void createEGLImage3DTextureSource(size_t width,
                                       size_t height,
                                       size_t depth,
                                       GLenum format,
                                       GLenum type,
                                       const EGLint *attribs,
                                       const void *data,
                                       GLTexture &sourceTexture,
                                       EGLImageKHR *outSourceImage)
    {
        // Create a source 3D texture
        glBindTexture(GL_TEXTURE_3D, sourceTexture);

        if (getClientMajorVersion() < 3)
        {
            ASSERT_TRUE(IsGLExtensionEnabled("GL_OES_texture_3D"));
            glTexImage3DOES(GL_TEXTURE_3D, 0, format, static_cast<GLsizei>(width),
                            static_cast<GLsizei>(height), static_cast<GLsizei>(depth), 0, format,
                            type, data);
        }
        else
        {
            glTexImage3D(GL_TEXTURE_3D, 0, format, static_cast<GLsizei>(width),
                         static_cast<GLsizei>(height), static_cast<GLsizei>(depth), 0, format, type,
                         data);
        }

        // Disable mipmapping
        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        ASSERT_GL_NO_ERROR();

        // Create an image from the source texture
        EGLWindow *window = getEGLWindow();

        EGLImageKHR image =
            eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_3D_KHR,
                              reinterpretHelper<EGLClientBuffer>(sourceTexture), attribs);

        ASSERT_EGL_SUCCESS();

        *outSourceImage = image;
    }

    void createEGLImageRenderbufferSource(size_t width,
                                          size_t height,
                                          GLenum internalFormat,
                                          const EGLint *attribs,
                                          GLRenderbuffer &sourceRenderbuffer,
                                          EGLImageKHR *outSourceImage)
    {
        // Create a source renderbuffer
        glBindRenderbuffer(GL_RENDERBUFFER, sourceRenderbuffer);
        glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, static_cast<GLsizei>(width),
                              static_cast<GLsizei>(height));

        // Create an image from the source renderbuffer
        EGLWindow *window = getEGLWindow();

        EGLImageKHR image =
            eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_RENDERBUFFER_KHR,
                              reinterpretHelper<EGLClientBuffer>(sourceRenderbuffer), attribs);

        ASSERT_EGL_SUCCESS();

        *outSourceImage = image;
    }

    void createEGLImageTargetTexture2D(EGLImageKHR image, GLTexture &targetTexture)
    {
        // Create a target texture from the image
        glBindTexture(GL_TEXTURE_2D, targetTexture);
        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);

        // Disable mipmapping
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        ASSERT_GL_NO_ERROR();
    }

    void createEGLImageTargetTexture2DArray(EGLImageKHR image, GLTexture &targetTexture)
    {
        // Create a target texture from the image
        glBindTexture(GL_TEXTURE_2D_ARRAY, targetTexture);
        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D_ARRAY, image);

        // Disable mipmapping
        glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        ASSERT_GL_NO_ERROR();
    }

    void createEGLImageTargetTextureExternal(EGLImageKHR image, GLuint targetTexture)
    {
        // Create a target texture from the image
        glBindTexture(GL_TEXTURE_EXTERNAL_OES, targetTexture);
        glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image);

        // Disable mipmapping
        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        ASSERT_GL_NO_ERROR();
    }

    void createEGLImageTargetTextureStorage(EGLImageKHR image,
                                            GLenum targetType,
                                            GLuint targetTexture,
                                            const GLint *attribs)
    {
        // Create a target texture from the image
        glBindTexture(targetType, targetTexture);
        glEGLImageTargetTexStorageEXT(targetType, image, attribs);

        ASSERT_GL_NO_ERROR();

        // Disable mipmapping
        glTexParameteri(targetType, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(targetType, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        ASSERT_GL_NO_ERROR();
    }

    size_t getLayerPitch(size_t height, size_t rowStride)
    {
        // Undocumented alignment of layer stride.  This is potentially platform dependent, but
        // allows functionality to be tested.
        constexpr size_t kLayerAlignment = 4096;

        const size_t layerSize = height * rowStride;
        return (layerSize + kLayerAlignment - 1) & ~(kLayerAlignment - 1);
    }

    struct AHBPlaneData
    {
        const GLubyte *data;
        size_t bytesPerPixel;
    };

    bool writeAHBData(AHardwareBuffer *aHardwareBuffer,
                      size_t width,
                      size_t height,
                      size_t depth,
                      bool isYUV,
                      const std::vector<AHBPlaneData> &data)
    {
#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
        ASSERT(!data.empty());
#    if defined(ANGLE_AHARDWARE_BUFFER_LOCK_PLANES_SUPPORT)
        AHardwareBuffer_Planes planeInfo;
        int res = AHardwareBuffer_lockPlanes(
            aHardwareBuffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY, -1, nullptr, &planeInfo);
        if (res != 0)
        {
            WARN() << "AHardwareBuffer_lockPlanes failed";
            return false;
        }

        EXPECT_EQ(data.size(), planeInfo.planeCount);

        for (size_t planeIdx = 0; planeIdx < data.size(); planeIdx++)
        {
            const AHBPlaneData &planeData      = data[planeIdx];
            const AHardwareBuffer_Plane &plane = planeInfo.planes[planeIdx];

            size_t planeHeight = (isYUV && planeIdx > 0) ? (height / 2) : height;
            size_t planeWidth  = (isYUV && planeIdx > 0) ? (width / 2) : width;
            size_t layerPitch  = getLayerPitch(planeHeight, plane.rowStride);

            for (size_t z = 0; z < depth; z++)
            {
                const uint8_t *srcDepthSlice =
                    reinterpret_cast<const uint8_t *>(planeData.data) +
                    z * planeHeight * planeWidth * planeData.bytesPerPixel;

                for (size_t y = 0; y < planeHeight; y++)
                {
                    const uint8_t *srcRow =
                        srcDepthSlice + y * planeWidth * planeData.bytesPerPixel;

                    for (size_t x = 0; x < planeWidth; x++)
                    {
                        const uint8_t *src = srcRow + x * planeData.bytesPerPixel;
                        uint8_t *dst = reinterpret_cast<uint8_t *>(plane.data) + z * layerPitch +
                                       y * plane.rowStride + x * plane.pixelStride;
                        memcpy(dst, src, planeData.bytesPerPixel);
                    }
                }
            }
        }

        res = AHardwareBuffer_unlock(aHardwareBuffer, nullptr);
        EXPECT_EQ(res, 0);
#    else
        EXPECT_EQ(1u, data.size());
        void *mappedMemory = nullptr;
        int res = AHardwareBuffer_lock(aHardwareBuffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY, -1,
                                       nullptr, &mappedMemory);
        EXPECT_EQ(res, 0);

        // Need to grab the stride the implementation might have enforced
        AHardwareBuffer_Desc aHardwareBufferDescription = {};
        AHardwareBuffer_describe(aHardwareBuffer, &aHardwareBufferDescription);
        const size_t stride = aHardwareBufferDescription.stride * data[0].bytesPerPixel;
        size_t layerPitch   = getLayerPitch(height, stride);

        uint32_t rowSize = stride * height;
        for (size_t z = 0; z < depth; z++)
        {
            for (uint32_t y = 0; y < height; y++)
            {
                size_t dstPtrOffset = z * layerPitch + y * stride;
                size_t srcPtrOffset = (z * height + y) * width * data[0].bytesPerPixel;

                uint8_t *dst = reinterpret_cast<uint8_t *>(mappedMemory) + dstPtrOffset;
                memcpy(dst, data[0].data + srcPtrOffset, rowSize);
            }
        }

        res = AHardwareBuffer_unlock(aHardwareBuffer, nullptr);
        EXPECT_EQ(res, 0);
#    endif
        return true;
#else
        return false;
#endif
    }

    enum AHBUsage
    {
        kAHBUsageGPUSampledImage   = 1 << 0,
        kAHBUsageGPUFramebuffer    = 1 << 1,
        kAHBUsageGPUCubeMap        = 1 << 2,
        kAHBUsageGPUMipMapComplete = 1 << 3,
        kAHBUsageFrontBuffer       = 1 << 4,
    };

    constexpr static uint32_t kDefaultAHBUsage = kAHBUsageGPUSampledImage | kAHBUsageGPUFramebuffer;
    constexpr static uint32_t kDefaultAHBYUVUsage = kAHBUsageGPUSampledImage;

#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
    AHardwareBuffer_Desc createAndroidHardwareBufferDesc(size_t width,
                                                         size_t height,
                                                         size_t depth,
                                                         int androidFormat,
                                                         uint32_t usage)
    {
        // The height and width are number of pixels of size format
        AHardwareBuffer_Desc aHardwareBufferDescription = {};
        aHardwareBufferDescription.width                = width;
        aHardwareBufferDescription.height               = height;
        aHardwareBufferDescription.layers               = depth;
        aHardwareBufferDescription.format               = androidFormat;
        aHardwareBufferDescription.usage                = AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY;
        if ((usage & kAHBUsageGPUSampledImage) != 0)
        {
            aHardwareBufferDescription.usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
        }
        if ((usage & kAHBUsageGPUFramebuffer) != 0)
        {
            aHardwareBufferDescription.usage |= AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
        }
        if ((usage & kAHBUsageGPUCubeMap) != 0)
        {
            aHardwareBufferDescription.usage |= AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
        }
        if ((usage & kAHBUsageGPUMipMapComplete) != 0)
        {
            aHardwareBufferDescription.usage |= AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE;
        }
        if ((usage & kAHBUsageFrontBuffer) != 0)
        {
            aHardwareBufferDescription.usage |= ANGLE_AHARDWAREBUFFER_USAGE_FRONT_BUFFER;
        }
        aHardwareBufferDescription.stride = 0;
        aHardwareBufferDescription.rfu0   = 0;
        aHardwareBufferDescription.rfu1   = 0;
        return aHardwareBufferDescription;
    }
#endif

    bool isAndroidHardwareBufferConfigurationSupported(size_t width,
                                                       size_t height,
                                                       size_t depth,
                                                       int androidFormat,
                                                       uint32_t usage)
    {
#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
        const AHardwareBuffer_Desc aHardwareBufferDescription =
            createAndroidHardwareBufferDesc(width, height, depth, androidFormat, usage);
        return AHardwareBuffer_isSupported(&aHardwareBufferDescription);
#else
        return false;
#endif
    }

    AHardwareBuffer *createAndroidHardwareBuffer(size_t width,
                                                 size_t height,
                                                 size_t depth,
                                                 int androidFormat,
                                                 uint32_t usage,
                                                 const std::vector<AHBPlaneData> &data)
    {
#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
        const AHardwareBuffer_Desc aHardwareBufferDescription =
            createAndroidHardwareBufferDesc(width, height, depth, androidFormat, usage);

        // Allocate memory from Android Hardware Buffer
        AHardwareBuffer *aHardwareBuffer = nullptr;
        EXPECT_EQ(0, AHardwareBuffer_allocate(&aHardwareBufferDescription, &aHardwareBuffer));

        if (!data.empty())
        {
            const bool isYUV = androidFormat == AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 ||
                               androidFormat == AHARDWAREBUFFER_FORMAT_YV12 ||
                               androidFormat == AHARDWAREBUFFER_FORMAT_YCbCr_P210;
            writeAHBData(aHardwareBuffer, width, height, depth, isYUV, data);
        }

        return aHardwareBuffer;
#else
        return nullptr;
#endif  // ANGLE_PLATFORM_ANDROID
    }

    void destroyAndroidHardwareBuffer(AHardwareBuffer *aHardwarebuffer)
    {
#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
        AHardwareBuffer_release(aHardwarebuffer);
#endif
    }

    void createEGLImageAndroidHardwareBufferSource(size_t width,
                                                   size_t height,
                                                   size_t depth,
                                                   int androidPixelFormat,
                                                   uint32_t usage,
                                                   const EGLint *attribs,
                                                   const std::vector<AHBPlaneData> &data,
                                                   AHardwareBuffer **outSourceAHB,
                                                   EGLImageKHR *outSourceImage)
    {
        // Set Android Memory
        AHardwareBuffer *aHardwareBuffer =
            createAndroidHardwareBuffer(width, height, depth, androidPixelFormat, usage, data);
        EXPECT_NE(aHardwareBuffer, nullptr);

        // Create an image from the source AHB
        EGLWindow *window = getEGLWindow();

        EGLImageKHR image = eglCreateImageKHR(
            window->getDisplay(), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
            angle::android::AHardwareBufferToClientBuffer(aHardwareBuffer), attribs);
        ASSERT_EGL_SUCCESS();

        *outSourceAHB   = aHardwareBuffer;
        *outSourceImage = image;
    }

    void createEGLImageANWBClientBufferSource(size_t width,
                                              size_t height,
                                              size_t depth,
                                              const EGLint *attribsANWB,
                                              const EGLint *attribsImage,
                                              const std::vector<AHBPlaneData> &data,
                                              EGLImageKHR *outSourceImage)
    {
        // Set Android Memory

        EGLClientBuffer eglClientBuffer = eglCreateNativeClientBufferANDROID(attribsANWB);
        EXPECT_NE(eglClientBuffer, nullptr);

        // allocate AHB memory
#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
        AHardwareBuffer *pAHardwareBuffer = angle::android::ANativeWindowBufferToAHardwareBuffer(
            angle::android::ClientBufferToANativeWindowBuffer(eglClientBuffer));
        if (!data.empty())
        {
            bool success = writeAHBData(pAHardwareBuffer, width, height, depth, false, data);
            if (!success)
            {
                return;
            }
        }
#endif  // ANGLE_AHARDWARE_BUFFER_SUPPORT

        // Create an image from the source eglClientBuffer
        EGLWindow *window = getEGLWindow();

        EGLImageKHR image =
            eglCreateImageKHR(window->getDisplay(), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
                              eglClientBuffer, attribsImage);
        ASSERT_EGL_SUCCESS();

        *outSourceImage = image;
    }

#if defined(ANGLE_ENABLE_WGPU)
    const DawnProcTable &getWebGPUProcs() { return dawn::native::GetProcs(); }

    WGPUDevice getWebGPUDevice()
    {
        EXPECT_TRUE(IsEGLClientExtensionEnabled("EGL_EXT_device_query"));
        EGLAttrib eglDevice = 0;
        EXPECT_EGL_TRUE(
            eglQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &eglDevice));
        EXPECT_TRUE(IsEGLDeviceExtensionEnabled(reinterpret_cast<EGLDeviceEXT>(eglDevice),
                                                kWebGPUDeviceExt));

        EGLAttrib wgpuDevice = 0;
        EXPECT_TRUE(eglQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(eglDevice),
                                            EGL_WEBGPU_DEVICE_ANGLE, &wgpuDevice));

        return reinterpret_cast<WGPUDevice>(wgpuDevice);
    }

    void createEGLImageWebGPUTextureClientBufferSource(const WGPUTextureDescriptor &desc,
                                                       const EGLint *attribsImage,
                                                       const std::vector<GLubyte> &data,
                                                       uint32_t bytesPerRow,
                                                       WGPUTexture *outSourceWebGPUTexture,
                                                       EGLImageKHR *outSourceImage)
    {
        const DawnProcTable &wgpu = getWebGPUProcs();

        WGPUDevice device   = getWebGPUDevice();
        WGPUTexture texture = wgpu.deviceCreateTexture(device, &desc);

        EGLImageKHR image = eglCreateImageKHR(getEGLWindow()->getDisplay(), EGL_NO_CONTEXT,
                                              EGL_WEBGPU_TEXTURE_ANGLE, texture, attribsImage);
        ASSERT_EGL_SUCCESS();

        if (!data.empty())
        {
            WGPUQueue queue = wgpu.deviceGetQueue(device);

            WGPUTexelCopyTextureInfo copyDest = WGPU_TEXEL_COPY_TEXTURE_INFO_INIT;
            copyDest.texture                  = texture;
            copyDest.mipLevel                 = 0;
            copyDest.origin                   = {0, 0, 0};

            WGPUTexelCopyBufferLayout dataLayout = WGPU_TEXEL_COPY_BUFFER_LAYOUT_INIT;
            dataLayout.bytesPerRow               = bytesPerRow;

            wgpu.queueWriteTexture(queue, &copyDest, data.data(), data.size(), &dataLayout,
                                   &desc.size);

            wgpu.queueRelease(queue);
        }

        wgpu.deviceRelease(device);

        *outSourceWebGPUTexture = texture;
        *outSourceImage         = image;
    }
#endif  // defined(ANGLE_ENABLE_WGPU)

    void createEGLImageTargetRenderbuffer(EGLImageKHR image, GLuint targetRenderbuffer)
    {
        // Create a target texture from the image
        glBindRenderbuffer(GL_RENDERBUFFER, targetRenderbuffer);
        glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, image);

        ASSERT_GL_NO_ERROR();
    }

    void ValidationGLEGLImage_helper(const EGLint *attribs);
    void SourceAHBTarget2D_helper(const EGLint *attribs);
    void SourceAHBTarget2DImageStorageGenerateMipmap_helper(const EGLint *attribs);
    void SourceAHBTarget2DArray_helper(const EGLint *attribs);
    void SourceAHBTargetExternal_helper(const EGLint *attribs);
    void SourceAHBTargetExternalESSL3_helper(const EGLint *attribs);
    void SourceNativeClientBufferTargetExternal_helper(const EGLint *attribs);
    void SourceNativeClientBufferTargetRenderbuffer_helper(const EGLint *attribs);
    void Source2DTarget2D_helper(const EGLint *attribs);
    void Source2DTarget2DArray_helper(const EGLint *attribs);
    void Source2DTargetRenderbuffer_helper(const EGLint *attribs);
    void Source2DTargetExternal_helper(const EGLint *attribs);
    void Source2DTargetExternalESSL3_helper(const EGLint *attribs);
    void SourceCubeTarget2D_helper(const EGLint *attribs);
    void SourceCubeTargetRenderbuffer_helper(const EGLint *attribs);
    void SourceCubeTargetExternal_helper(const EGLint *attribs);
    void SourceCubeTargetExternalESSL3_helper(const EGLint *attribs);
    void Source3DTargetTexture_helper(EGLint *attribs);
    void Source3DTargetRenderbuffer_helper(EGLint *attribs);
    void Source3DTargetExternal_helper(EGLint *attribs);
    void Source3DTargetExternalESSL3_helper(EGLint *attribs);
    void SourceRenderbufferTargetTexture_helper(const EGLint *attribs);
    void SourceRenderbufferTargetTextureExternal_helper(const EGLint *attribs);
    void SourceRenderbufferTargetRenderbuffer_helper(const EGLint *attribs);
    void FixedRatedCompressionBasicHelper(const GLint *attribs);
    void FixedRatedCompressionImageAttribCheck(EGLImageKHR image,
                                               const GLint *attribs,
                                               const GLint expectResult);
    void SourceRenderbufferTargetTextureExternalESSL3_helper(const EGLint *attribs);
    void ImageStorageGenerateMipmap_helper(const EGLint *attribs,
                                           const GLsizei width,
                                           const GLsizei height,
                                           AHardwareBuffer *srcAhb,
                                           GLuint srcTexture,
                                           EGLImageKHR *imageOut);
    void ImageCheckingTextureAccessHelper(GLenum target, bool mipmap);
    void verifyImageStorageMipmap(const EGLint *attribs,
                                  EGLImageKHR image,
                                  const GLsizei mipLevelCount);
    void verifyImageStorageMipmapWithBlend(const EGLint *attribs,
                                           EGLImageKHR image,
                                           const GLsizei mipLevelCount);
    void verifyResultsTexture(GLuint texture,
                              const GLubyte referenceColor[4],
                              GLenum textureTarget,
                              GLuint program,
                              GLuint textureUniform)
    {
        // Draw a quad with the target texture
        glUseProgram(program);
        glBindTexture(textureTarget, texture);
        glUniform1i(textureUniform, 0);

        drawQuad(program, "position", 0.5f);

        // Expect that the rendered quad's color is the same as the reference color with a tolerance
        // of 2
        EXPECT_PIXEL_NEAR(0, 0, referenceColor[0], referenceColor[1], referenceColor[2],
                          referenceColor[3], 2);
    }

    void verifyResultsTextureLeftAndRight(GLuint texture,
                                          const GLubyte leftColor[4],
                                          const GLubyte rightColor[4],
                                          GLenum textureTarget,
                                          GLuint program,
                                          GLuint textureUniform)
    {
        verifyResultsTexture(texture, leftColor, textureTarget, program, textureUniform);

        // verifyResultsTexture only verifies top-left. Here also verifies top-right.
        EXPECT_PIXEL_NEAR(getWindowWidth() - 1, 0, rightColor[0], rightColor[1], rightColor[2],
                          rightColor[3], 1);
    }

    void verifyResults2D(GLuint texture, const GLubyte data[4])
    {
        verifyResultsTexture(texture, data, GL_TEXTURE_2D, mTextureProgram,
                             mTextureUniformLocation);
    }

    void verifyResults3D(GLuint texture,
                         const GLubyte data[4],
                         uint32_t layerIndex,
                         uint32_t totalLayers)
    {
        glUseProgram(m3DTextureProgram);
        float layerInterval = 1.0f / totalLayers;
        float layerCenter   = ((layerIndex + 1) * 1.0f / totalLayers) - layerInterval / 2.0f;
        glUniform1f(m3DTextureLayerUniformLocation, layerCenter);

        verifyResultsTexture(texture, data, GL_TEXTURE_3D, m3DTextureProgram,
                             m3DTextureUniformLocation);
    }

    void verifyResults2DLeftAndRight(GLuint texture, const GLubyte left[4], const GLubyte right[4])
    {
        verifyResultsTextureLeftAndRight(texture, left, right, GL_TEXTURE_2D, mTextureProgram,
                                         mTextureUniformLocation);
    }

    void verifyResults2DArray(GLuint texture, const GLubyte data[4], uint32_t layerIndex = 0)
    {
        glUseProgram(m2DArrayTextureProgram);
        glUniform1ui(m2DArrayTextureLayerUniformLocation, layerIndex);

        verifyResultsTexture(texture, data, GL_TEXTURE_2D_ARRAY, m2DArrayTextureProgram,
                             m2DArrayTextureUniformLocation);
    }

    void verifyResultsCube(GLuint texture, const GLubyte data[4], uint32_t faceIndex = 0)
    {
        glUseProgram(mCubeTextureProgram);
        glUniform3f(mCubeTextureFaceCoordUniformLocation, kCubeFaceX[faceIndex],
                    kCubeFaceY[faceIndex], kCubeFaceZ[faceIndex]);

        verifyResultsTexture(texture, data, GL_TEXTURE_CUBE_MAP, mCubeTextureProgram,
                             mCubeTextureUniformLocation);
    }

    void verifyResultsCubeArray(GLuint texture,
                                const GLubyte data[4],
                                uint32_t faceIndex  = 0,
                                uint32_t layerIndex = 0)
    {
        glUseProgram(mCubeArrayTextureProgram);
        glUniform1ui(mCubeArrayTextureLayerUniformLocation, layerIndex);
        glUniform3f(mCubeArrayTextureFaceCoordUniformLocation, kCubeFaceX[faceIndex],
                    kCubeFaceY[faceIndex], kCubeFaceZ[faceIndex]);

        verifyResultsTexture(texture, data, GL_TEXTURE_CUBE_MAP_ARRAY, mCubeArrayTextureProgram,
                             mCubeArrayTextureUniformLocation);
    }

    void verifyResultsExternal(GLuint texture, const GLubyte data[4])
    {
        verifyResultsTexture(texture, data, GL_TEXTURE_EXTERNAL_OES, mTextureExternalProgram,
                             mTextureExternalUniformLocation);
    }

    void verifyResultsExternalESSL3(GLuint texture, const GLubyte data[4])
    {
        verifyResultsTexture(texture, data, GL_TEXTURE_EXTERNAL_OES, mTextureExternalESSL3Program,
                             mTextureExternalESSL3UniformLocation);
    }

    void verifyResultsExternalYUV(GLuint texture, const GLubyte data[4])
    {
        verifyResultsTexture(texture, data, GL_TEXTURE_EXTERNAL_OES, mTextureYUVProgram,
                             mTextureYUVUniformLocation);
    }

    void verifyResultsExternalYUVVS(GLuint texture, const GLubyte data[4])
    {
        verifyResultsTexture(texture, data, GL_TEXTURE_EXTERNAL_OES, mTextureYUVVSProgram,
                             mTextureYUVVSUniformLocation);
    }

    void verifyResultsExternalYUVFetch(GLuint texture, const GLubyte data[4])
    {
        verifyResultsTexture(texture, data, GL_TEXTURE_EXTERNAL_OES, mFetchYUVProgram,
                             mFetchYUVUniformLocation);
    }

    void verifyResultsExternalYUVFetchVS(GLuint texture, const GLubyte data[4])
    {
        verifyResultsTexture(texture, data, GL_TEXTURE_EXTERNAL_OES, mFetchYUVVSProgram,
                             mFetchYUVVSUniformLocation);
    }

    void verifyResultsRenderbuffer(GLuint renderbuffer, GLubyte referenceColor[4])
    {
        // Bind the renderbuffer to a framebuffer
        GLFramebuffer framebuffer;
        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
                                  renderbuffer);

        // Expect renderbuffer to match referenceColor with a tolerance of 1.
        EXPECT_PIXEL_NEAR(0, 0, referenceColor[0], referenceColor[1], referenceColor[2],
                          referenceColor[3], 1);
    }

    void verifyResultsRenderbufferWithClearAndDraw(GLuint texture,
                                                   GLuint renderbuffer,
                                                   GLubyte clearColor[4],
                                                   GLubyte referenceColor[4])
    {
        // Bind the renderbuffer to a framebuffer
        GLFramebuffer framebuffer;
        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
                                  renderbuffer);

        // Clear the renderbuffer with the clear color
        glClearColor(clearColor[0] / 255.0f, clearColor[1] / 255.0f, clearColor[2] / 255.0f,
                     clearColor[3] / 255.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // Expect renderbuffer to match referenceColor with a tolerance of 1.
        EXPECT_PIXEL_NEAR(0, 0, referenceColor[0], referenceColor[1], referenceColor[2],
                          referenceColor[3], 1);

        // Sample source texture and draw onto renderbuffer and expect rendered quad's color
        // is the same as the reference color with a tolerance of 1
        verifyResultsTexture(texture, referenceColor, GL_TEXTURE_2D, mTextureProgram,
                             mTextureUniformLocation);
    }

    enum class AHBVerifyRegion
    {
        Entire,
        LeftHalf,
        RightHalf,
    };

    void verifyResultAHB(AHardwareBuffer *source,
                         const std::vector<AHBPlaneData> &data,
                         AHBVerifyRegion verifyRegion = AHBVerifyRegion::Entire)
    {
#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
        AHardwareBuffer_Desc aHardwareBufferDescription;
        AHardwareBuffer_describe(source, &aHardwareBufferDescription);
        bool isYUV = (aHardwareBufferDescription.format == AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420);
        const uint32_t width  = aHardwareBufferDescription.width;
        const uint32_t height = aHardwareBufferDescription.height;
        const uint32_t depth  = aHardwareBufferDescription.layers;

#    if defined(ANGLE_AHARDWARE_BUFFER_LOCK_PLANES_SUPPORT)
        AHardwareBuffer_Planes planeInfo;
        ASSERT_EQ(0, AHardwareBuffer_lockPlanes(source, AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY, -1,
                                                nullptr, &planeInfo));
        ASSERT_EQ(data.size(), planeInfo.planeCount);

        for (size_t planeIdx = 0; planeIdx < data.size(); planeIdx++)
        {
            const AHBPlaneData &planeData      = data[planeIdx];
            const AHardwareBuffer_Plane &plane = planeInfo.planes[planeIdx];

            const size_t planeHeight = (isYUV && planeIdx > 0) ? (height / 2) : height;
            const size_t planeWidth  = (isYUV && planeIdx > 0) ? (width / 2) : width;
            size_t layerPitch        = getLayerPitch(planeHeight, plane.rowStride);

            uint32_t xStart = 0;
            uint32_t xEnd   = planeWidth;

            switch (verifyRegion)
            {
                case AHBVerifyRegion::Entire:
                    break;
                case AHBVerifyRegion::LeftHalf:
                    xEnd = planeWidth / 2;
                    break;
                case AHBVerifyRegion::RightHalf:
                    xStart = planeWidth / 2;
                    break;
            }

            for (size_t z = 0; z < depth; z++)
            {
                const uint8_t *referenceDepthSlice =
                    reinterpret_cast<const uint8_t *>(planeData.data) +
                    z * planeHeight * (xEnd - xStart) * planeData.bytesPerPixel;
                for (size_t y = 0; y < planeHeight; y++)
                {
                    const uint8_t *referenceRow =
                        referenceDepthSlice + y * (xEnd - xStart) * planeData.bytesPerPixel;
                    for (size_t x = xStart; x < xEnd; x++)
                    {
                        const uint8_t *referenceData =
                            referenceRow + (x - xStart) * planeData.bytesPerPixel;
                        std::vector<uint8_t> reference(referenceData,
                                                       referenceData + planeData.bytesPerPixel);

                        const uint8_t *ahbData = reinterpret_cast<uint8_t *>(plane.data) +
                                                 z * layerPitch + y * plane.rowStride +
                                                 x * plane.pixelStride;
                        std::vector<uint8_t> ahb(ahbData, ahbData + planeData.bytesPerPixel);

                        EXPECT_EQ(reference, ahb)
                            << "at (" << x << ", " << y << ") on plane " << planeIdx;
                    }
                }
            }
        }
        ASSERT_EQ(0, AHardwareBuffer_unlock(source, nullptr));
#    else
        ASSERT_EQ(1u, data.size());
        ASSERT_FALSE(isYUV);

        const uint32_t rowStride = aHardwareBufferDescription.stride * data[0].bytesPerPixel;
        size_t layerPitch        = getLayerPitch(height, rowStride);

        void *mappedMemory = nullptr;
        ASSERT_EQ(0, AHardwareBuffer_lock(source, AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY, -1,
                                          nullptr, &mappedMemory));

        uint32_t xStart = 0;
        uint32_t xEnd   = width;

        switch (verifyRegion)
        {
            case AHBVerifyRegion::Entire:
                break;
            case AHBVerifyRegion::LeftHalf:
                xEnd = width / 2;
                break;
            case AHBVerifyRegion::RightHalf:
                xStart = width / 2;
                break;
        }
        for (size_t z = 0; z < depth; z++)
        {
            const uint8_t *referenceDepthSlice =
                reinterpret_cast<const uint8_t *>(data[0].data) +
                z * height * (xEnd - xStart) * data[0].bytesPerPixel;
            for (size_t y = 0; y < height; y++)
            {
                const uint8_t *referenceRow =
                    referenceDepthSlice + y * (xEnd - xStart) * data[0].bytesPerPixel;
                for (size_t x = xStart; x < xEnd; x++)
                {
                    const uint8_t *referenceData =
                        referenceRow + (x - xStart) * data[0].bytesPerPixel;
                    std::vector<uint8_t> reference(referenceData,
                                                   referenceData + data[0].bytesPerPixel);

                    const uint8_t *ahbData = reinterpret_cast<uint8_t *>(mappedMemory) +
                                             z * layerPitch + y * rowStride +
                                             x * data[0].bytesPerPixel;
                    std::vector<uint8_t> ahb(ahbData, ahbData + data[0].bytesPerPixel);

                    EXPECT_EQ(reference, ahb) << "at (" << x << ", " << y << ")";
                }
            }
        }
        ASSERT_EQ(0, AHardwareBuffer_unlock(source, nullptr));
#    endif
#endif
    }

    template <typename destType, typename sourcetype>
    destType reinterpretHelper(const sourcetype &source)
    {
        static_assert(sizeof(destType) == sizeof(size_t),
                      "destType should be the same size as a size_t");
        size_t sourceSizeT = static_cast<size_t>(source.get());
        return reinterpret_cast<destType>(sourceSizeT);
    }

    bool hasImageGLColorspaceExt() const
    {
        // Possible GLES driver bug on Pixel2 devices: http://anglebug.com/42263865
        if (IsPixel2() && IsOpenGLES())
        {
            return false;
        }
        return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), kImageGLColorspaceExt);
    }

    bool hasAndroidImageNativeBufferExt() const
    {
        return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(),
                                            kEGLAndroidImageNativeBufferExt);
    }

    bool hasEglImageStorageExt() const { return IsGLExtensionEnabled(kEGLImageStorageExt); }

    bool hasEglImageStorageCompressionExt() const
    {
        return IsGLExtensionEnabled(kEGLImageStorageCompressionExt);
    }

    bool hasTextureStorageCompressionExt() const
    {
        return IsGLExtensionEnabled(kTextureStorageCompressionExt);
    }

    bool hasAndroidHardwareBufferSupport() const
    {
#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
        return true;
#else
        return false;
#endif
    }

    bool hasAhbLockPlanesSupport() const
    {
#if defined(ANGLE_AHARDWARE_BUFFER_LOCK_PLANES_SUPPORT)
        return true;
#else
        return false;
#endif
    }

    bool hasEglImageArrayExt() const { return IsGLExtensionEnabled(kEGLImageArrayExt); }

    bool hasOESExt() const { return IsGLExtensionEnabled(kOESExt); }

    bool hasExternalExt() const { return IsGLExtensionEnabled(kExternalExt); }

    bool hasExternalESSL3Ext() const { return IsGLExtensionEnabled(kExternalESSL3Ext); }

    bool hasYUVInternalFormatExt() const { return IsGLExtensionEnabled(kYUVInternalFormatExt); }

    bool hasYUVTargetExt() const { return IsGLExtensionEnabled(kYUVTargetExt); }

    bool hasRGBXInternalFormatExt() const { return IsGLExtensionEnabled(kRGBXInternalFormatExt); }

    bool hasBaseExt() const
    {
        return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), kBaseExt);
    }

    bool has2DTextureExt() const
    {
        return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), k2DTextureExt);
    }

    bool has3DTextureExt() const
    {
        return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), k3DTextureExt);
    }

    bool hasPixmapExt() const
    {
        return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), kPixmapExt);
    }

    bool hasRenderbufferExt() const
    {
        return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), kRenderbufferExt);
    }

    bool hasCubemapExt() const
    {
        return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), kCubemapExt);
    }

    bool hasWebGPUDeviceExt() const
    {
        if (!IsEGLClientExtensionEnabled("EGL_EXT_device_query"))
        {
            return false;
        }
        EGLAttrib device = 0;
        EXPECT_EGL_TRUE(
            eglQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &device));
        return IsEGLDeviceExtensionEnabled(reinterpret_cast<EGLDeviceEXT>(device),
                                           kWebGPUDeviceExt);
    }

    bool hasWebGPUTextureExt() const
    {
        return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), kWebGPUTextureExt);
    }

    angle::VulkanPerfCounters getPerfCounters()
    {
        ASSERT(IsVulkan());

        if (mCounterNameToIndexMap.empty())
        {
            mCounterNameToIndexMap = BuildCounterNameToIndexMap();
        }

        return GetPerfCounters(mCounterNameToIndexMap);
    }

    void externalTextureTracerTestHelper(const EGLint *attribsToRecoverInMEC)
    {
        const EGLWindow *eglWindow = getEGLWindow();
        // Frame 1 begins
        // Create the Image
        GLTexture sourceTexture1;
        EGLImageKHR image1;

        GLubyte data[] = {132, 55, 219, 255};
        // Create a source 2D texture
        glBindTexture(GL_TEXTURE_2D, sourceTexture1);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast<GLsizei>(1), static_cast<GLsizei>(1), 0,
                     GL_RGBA, GL_UNSIGNED_BYTE, data);

        // Disable mipmapping
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        ASSERT_GL_NO_ERROR();

        image1 = eglCreateImageKHR(
            eglWindow->getDisplay(), eglWindow->getContext(), EGL_GL_TEXTURE_2D_KHR,
            reinterpretHelper<EGLClientBuffer>(sourceTexture1), attribsToRecoverInMEC);

        ASSERT_EGL_SUCCESS();

        // Create the target
        GLTexture targetTexture1;
        // Create a target texture from the image
        glBindTexture(GL_TEXTURE_EXTERNAL_OES, targetTexture1);
        glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image1);

        // Disable mipmapping
        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        ASSERT_GL_NO_ERROR();

        // Calls On EndFrame(), with MidExecutionSetup to restore external texture targetTexture1
        // above
        EGLDisplay display = eglWindow->getDisplay();
        EGLSurface surface = eglWindow->getSurface();
        eglSwapBuffers(display, surface);
        // Frame 1 ends

        // Frame 2 begins
        // Create another eglImage with another associated texture
        // Draw using the eglImage texture targetTexture1 created in frame 1
        GLTexture sourceTexture2;
        EGLImageKHR image2;

        // Create a source 2D texture
        glBindTexture(GL_TEXTURE_2D, sourceTexture2);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast<GLsizei>(1), static_cast<GLsizei>(1), 0,
                     GL_RGBA, GL_UNSIGNED_BYTE, data);

        // Disable mipmapping
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        ASSERT_GL_NO_ERROR();

        constexpr EGLint defaultAttribs[] = {
            EGL_IMAGE_PRESERVED,
            EGL_TRUE,
            EGL_NONE,
        };
        image2 = eglCreateImageKHR(
            eglWindow->getDisplay(), eglWindow->getContext(), EGL_GL_TEXTURE_2D_KHR,
            reinterpretHelper<EGLClientBuffer>(sourceTexture2), defaultAttribs);

        ASSERT_EGL_SUCCESS();

        // Create the target
        GLTexture targetTexture2;
        // Create a target texture from the image
        glBindTexture(GL_TEXTURE_EXTERNAL_OES, targetTexture2);
        glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image2);

        // Disable mipmapping
        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        ASSERT_GL_NO_ERROR();
        glUseProgram(mTextureExternalProgram);
        glBindTexture(GL_TEXTURE_EXTERNAL_OES, targetTexture1);
        glUniform1i(mTextureExternalUniformLocation, 0);

        drawQuad(mTextureExternalProgram, "position", 0.5f);

        // Calls On EndFrame() to save the gl calls creating external texture targetTexture2;
        // We use this as a reference to check the gl calls we restore for targetTexture1
        // in MidExecutionSetup
        eglSwapBuffers(display, surface);
        // Frame 2 ends

        // Frame 3 begins
        // Draw a quad with the targetTexture2
        glUseProgram(mTextureExternalProgram);
        glBindTexture(GL_TEXTURE_EXTERNAL_OES, targetTexture2);
        glUniform1i(mTextureExternalUniformLocation, 0);

        drawQuad(mTextureExternalProgram, "position", 0.5f);

        eglSwapBuffers(display, surface);
        // Frame 3 ends

        // Clean up
        eglDestroyImageKHR(eglWindow->getDisplay(), image1);
        eglDestroyImageKHR(eglWindow->getDisplay(), image2);
    }

    void framebufferAttachmentDeletedWhileInUseHelper(bool useTextureAttachment,
                                                      bool deleteSourceTextureLast);
    void framebufferResolveAttachmentDeletedWhileInUseHelper(bool useTextureAttachment,
                                                             bool deleteSourceTextureLast);
    void useAHBByGLThenForeignThenGLHelper(
        std::function<void(const GLTexture &, uint32_t, uint32_t)> firstUse,
        std::function<void(const GLTexture &, uint32_t, uint32_t)> secondUse);

    EGLint default3DAttribs[5] = {
        EGL_GL_TEXTURE_ZOFFSET_KHR, static_cast<EGLint>(0), EGL_IMAGE_PRESERVED, EGL_TRUE, EGL_NONE,
    };
    EGLint colorspace3DAttribs[7] = {
        EGL_GL_TEXTURE_ZOFFSET_KHR,
        static_cast<EGLint>(0),
        EGL_IMAGE_PRESERVED,
        EGL_TRUE,
        EGL_GL_COLORSPACE,
        EGL_GL_COLORSPACE_SRGB_KHR,
        EGL_NONE,
    };
    GLuint mTextureProgram;
    GLuint m2DArrayTextureProgram;
    GLuint m3DTextureProgram;
    GLuint mCubeTextureProgram;
    GLuint mCubeArrayTextureProgram;
    GLint mTextureUniformLocation;
    GLuint m2DArrayTextureUniformLocation;
    GLuint m2DArrayTextureLayerUniformLocation;
    GLuint m3DTextureUniformLocation;
    GLuint m3DTextureLayerUniformLocation;
    GLuint mCubeTextureUniformLocation;
    GLuint mCubeTextureFaceCoordUniformLocation;
    GLuint mCubeArrayTextureUniformLocation;
    GLuint mCubeArrayTextureFaceCoordUniformLocation;
    GLuint mCubeArrayTextureLayerUniformLocation;

    GLuint mTextureExternalProgram        = 0;
    GLint mTextureExternalUniformLocation = -1;

    GLuint mTextureExternalESSL3Program        = 0;
    GLint mTextureExternalESSL3UniformLocation = -1;

    GLuint mTextureYUVProgram        = 0;
    GLint mTextureYUVUniformLocation = -1;

    GLuint mTextureYUVVSProgram        = 0;
    GLint mTextureYUVVSUniformLocation = -1;

    GLuint mFetchYUVProgram          = 0;
    GLint mFetchYUVUniformLocation   = -1;
    GLuint mFetchYUVVSProgram        = 0;
    GLint mFetchYUVVSUniformLocation = -1;

    GLuint mRenderYUVProgram        = 0;
    GLuint mRenderYUVProgram2       = 0;
    GLint mRenderYUVUniformLocation = -1;

    CounterNameToIndexMap mCounterNameToIndexMap;
};

class ImageTestES3 : public ImageTest
{};

class ImageTestES31 : public ImageTest
{};

// Tests that the extension is exposed on the platforms we think it should be. Please modify this as
// you change extension availability.
TEST_P(ImageTest, ANGLEExtensionAvailability)
{
    // EGL support is based on driver extension availability.
    ANGLE_SKIP_TEST_IF(IsOpenGLES() && IsAndroid());
    ANGLE_SKIP_TEST_IF(IsOpenGLES() && IsOzone());

    if (IsD3D11() || IsD3D9())
    {
        EXPECT_TRUE(hasOESExt());
        EXPECT_TRUE(hasExternalExt());
        EXPECT_TRUE(hasBaseExt());
        EXPECT_TRUE(has2DTextureExt());
        EXPECT_TRUE(hasRenderbufferExt());
        EXPECT_FALSE(has3DTextureExt());

        if (IsD3D11())
        {
            EXPECT_TRUE(hasCubemapExt());

            if (getClientMajorVersion() >= 3)
            {
                EXPECT_TRUE(hasExternalESSL3Ext());
            }
            else
            {
                EXPECT_FALSE(hasExternalESSL3Ext());
            }
        }
        else
        {
            EXPECT_FALSE(hasCubemapExt());
            EXPECT_FALSE(hasExternalESSL3Ext());
        }
    }
    else if (IsVulkan())
    {
        EXPECT_TRUE(hasOESExt());
        EXPECT_TRUE(hasExternalExt());
        EXPECT_TRUE(hasBaseExt());
        EXPECT_TRUE(has2DTextureExt());
        EXPECT_TRUE(hasCubemapExt());
        EXPECT_TRUE(hasRenderbufferExt());
        if (getClientMajorVersion() >= 3)
        {
            EXPECT_TRUE(hasExternalESSL3Ext());
        }
        else
        {
            EXPECT_FALSE(hasExternalESSL3Ext());
        }
    }
    else if (IsMetal())
    {
        // NOTE(hqle): Metal currently doesn't implement any image extensions besides
        // EGL_ANGLE_metal_texture_client_buffer
        EXPECT_TRUE(hasOESExt());
        EXPECT_TRUE(hasBaseExt());
        EXPECT_FALSE(hasExternalExt());
        EXPECT_FALSE(hasExternalESSL3Ext());
        EXPECT_FALSE(has2DTextureExt());
        EXPECT_FALSE(has3DTextureExt());
        EXPECT_FALSE(hasRenderbufferExt());
    }
    else if (IsWebGPU())
    {
        EXPECT_TRUE(hasOESExt());
        EXPECT_TRUE(hasBaseExt());
        EXPECT_TRUE(hasExternalExt());
        if (getClientMajorVersion() >= 3)
        {
            EXPECT_TRUE(hasExternalESSL3Ext());
        }
        else
        {
            EXPECT_FALSE(hasExternalESSL3Ext());
        }
        EXPECT_TRUE(has2DTextureExt());
        EXPECT_FALSE(hasCubemapExt());
        EXPECT_FALSE(has3DTextureExt());
        EXPECT_TRUE(hasRenderbufferExt());
        EXPECT_TRUE(hasWebGPUDeviceExt());
        EXPECT_TRUE(hasWebGPUTextureExt());
#if !defined(ANGLE_ENABLE_WGPU)
        FAIL() << "ANGLE_ENABLE_WGPU not defined when running on WebGPU backend";
#endif
    }
    else
    {
        EXPECT_FALSE(hasOESExt());
        EXPECT_FALSE(hasExternalExt());
        EXPECT_FALSE(hasExternalESSL3Ext());
        EXPECT_FALSE(hasBaseExt());
        EXPECT_FALSE(has2DTextureExt());
        EXPECT_FALSE(has3DTextureExt());
        EXPECT_FALSE(hasRenderbufferExt());
    }

    // These extensions are not yet available on any platform.
    EXPECT_FALSE(hasPixmapExt());
}

// Check validation from the EGL_KHR_image_base extension
TEST_P(ImageTest, ValidationImageBase)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    GLTexture glTexture2D;
    glBindTexture(GL_TEXTURE_2D, glTexture2D);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    EGLDisplay display        = window->getDisplay();
    EGLContext context        = window->getContext();
    EGLConfig config          = window->getConfig();
    EGLImageKHR image         = EGL_NO_IMAGE_KHR;
    EGLClientBuffer texture2D = reinterpretHelper<EGLClientBuffer>(glTexture2D);

    // Test validation of eglCreateImageKHR

    // If <dpy> is not the handle of a valid EGLDisplay object, the error EGL_BAD_DISPLAY is
    // generated.
    image = eglCreateImageKHR(reinterpret_cast<EGLDisplay>(0xBAADF00D), context,
                              EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr);
    EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
    EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);

    // If <ctx> is neither the handle of a valid EGLContext object on <dpy> nor EGL_NO_CONTEXT, the
    // error EGL_BAD_CONTEXT is generated.
    image = eglCreateImageKHR(display, reinterpret_cast<EGLContext>(0xBAADF00D),
                              EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr);
    EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
    EXPECT_EGL_ERROR(EGL_BAD_CONTEXT);

    // Test EGL_NO_CONTEXT with a 2D texture target which does require a context.
    image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr);
    EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
    EXPECT_EGL_ERROR(EGL_BAD_CONTEXT);

    // If an attribute specified in <attrib_list> is not one of the attributes listed in Table bbb,
    // the error EGL_BAD_PARAMETER is generated.
    EGLint badAttributes[] = {
        static_cast<EGLint>(0xDEADBEEF),
        0,
        EGL_NONE,
    };

    image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, texture2D, badAttributes);
    EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
    EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);

    // If the resource specified by <dpy>, <ctx>, <target>, <buffer> and <attrib_list> has an off -
    // screen buffer bound to it(e.g., by a
    // previous call to eglBindTexImage), the error EGL_BAD_ACCESS is generated.
    EGLint surfaceType = 0;
    eglGetConfigAttrib(display, config, EGL_SURFACE_TYPE, &surfaceType);

    EGLint bindToTextureRGBA = 0;
    eglGetConfigAttrib(display, config, EGL_BIND_TO_TEXTURE_RGBA, &bindToTextureRGBA);
    if ((surfaceType & EGL_PBUFFER_BIT) != 0 && bindToTextureRGBA == EGL_TRUE)
    {
        EGLint pbufferAttributes[] = {
            EGL_WIDTH,          1,
            EGL_HEIGHT,         1,
            EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
            EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
            EGL_NONE,           EGL_NONE,
        };
        EGLSurface pbuffer = eglCreatePbufferSurface(display, config, pbufferAttributes);
        ASSERT_NE(pbuffer, EGL_NO_SURFACE);
        EXPECT_EGL_SUCCESS();

        eglBindTexImage(display, pbuffer, EGL_BACK_BUFFER);
        EXPECT_EGL_SUCCESS();

        image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr);
        EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
        EXPECT_EGL_ERROR(EGL_BAD_ACCESS);

        eglReleaseTexImage(display, pbuffer, EGL_BACK_BUFFER);
        eglDestroySurface(display, pbuffer);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
        EXPECT_EGL_SUCCESS();
        EXPECT_GL_NO_ERROR();
    }

    // If the resource specified by <dpy>, <ctx>, <target>, <buffer> and
    // <attrib_list> is itself an EGLImage sibling, the error EGL_BAD_ACCESS is generated.
    image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr);
    EXPECT_NE(image, EGL_NO_IMAGE_KHR);
    EXPECT_EGL_SUCCESS();

    /* TODO(geofflang): Enable this validation when it passes.
    EGLImageKHR image2 = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
    reinterpret_cast<EGLClientBuffer>(texture2D), nullptr);
    EXPECT_EQ(image2, EGL_NO_IMAGE_KHR);
    EXPECT_EGL_ERROR(EGL_BAD_ACCESS);
    */

    // Test validation of eglDestroyImageKHR
    // Note: image is now a valid EGL image
    EGLBoolean result = EGL_FALSE;

    // If <dpy> is not the handle of a valid EGLDisplay object, the error EGL_BAD_DISPLAY is
    // generated.
    result = eglDestroyImageKHR(reinterpret_cast<EGLDisplay>(0xBAADF00D), image);
    EXPECT_EQ(result, static_cast<EGLBoolean>(EGL_FALSE));
    EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);

    // If <image> is not a valid EGLImageKHR object created with respect to <dpy>, the error
    // EGL_BAD_PARAMETER is generated.
    result = eglDestroyImageKHR(display, reinterpret_cast<EGLImageKHR>(0xBAADF00D));
    EXPECT_EQ(result, static_cast<EGLBoolean>(EGL_FALSE));
    EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);

    // Clean up and validate image is destroyed
    result = eglDestroyImageKHR(display, image);
    EXPECT_EQ(result, static_cast<EGLBoolean>(EGL_TRUE));
    EXPECT_EGL_SUCCESS();

    EXPECT_GL_NO_ERROR();
}

// Check validation from the EGL_KHR_gl_texture_2D_image, EGL_KHR_gl_texture_cubemap_image,
// EGL_KHR_gl_texture_3D_image and EGL_KHR_gl_renderbuffer_image extensions
TEST_P(ImageTest, ValidationGLImage)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt());

    EGLDisplay display = window->getDisplay();
    EGLContext context = window->getContext();
    EGLImageKHR image  = EGL_NO_IMAGE_KHR;

    if (has2DTextureExt())
    {
        // If <target> is EGL_GL_TEXTURE_2D_KHR, EGL_GL_TEXTURE_CUBE_MAP_*_KHR or
        // EGL_GL_TEXTURE_3D_KHR and <buffer> is not the name of a texture object of type <target>,
        // the error EGL_BAD_PARAMETER is generated.
        GLTexture textureCube;
        glBindTexture(GL_TEXTURE_CUBE_MAP, textureCube);
        for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
             face++)
        {
            glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
        }

        image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
                                  reinterpretHelper<EGLClientBuffer>(textureCube), nullptr);
        EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
        EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);

        // If EGL_GL_TEXTURE_LEVEL_KHR is 0, <target> is EGL_GL_TEXTURE_2D_KHR,
        // EGL_GL_TEXTURE_CUBE_MAP_*_KHR or EGL_GL_TEXTURE_3D_KHR, <buffer> is the name of an
        // incomplete GL texture object, and any mipmap levels other than mipmap level 0 are
        // specified, the error EGL_BAD_PARAMETER is generated.
        GLTexture incompleteTexture;
        glBindTexture(GL_TEXTURE_2D, incompleteTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
        glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

        EGLint level0Attribute[] = {
            EGL_GL_TEXTURE_LEVEL_KHR,
            0,
            EGL_NONE,
        };
        image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
                                  reinterpretHelper<EGLClientBuffer>(incompleteTexture),
                                  level0Attribute);
        EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
        EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);

        // If EGL_GL_TEXTURE_LEVEL_KHR is 0, <target> is EGL_GL_TEXTURE_2D_KHR or
        // EGL_GL_TEXTURE_3D_KHR, <buffer> is not the name of a complete GL texture object, and
        // mipmap level 0 is not specified, the error EGL_BAD_PARAMETER is generated.
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
        image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
                                  reinterpretHelper<EGLClientBuffer>(incompleteTexture), nullptr);
        EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
        EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);

        // If <target> is EGL_GL_TEXTURE_2D_KHR, EGL_GL_TEXTURE_CUBE_MAP_*_KHR,
        // EGL_GL_RENDERBUFFER_KHR or EGL_GL_TEXTURE_3D_KHR and <buffer> refers to the default GL
        // texture object(0) for the corresponding GL target, the error EGL_BAD_PARAMETER is
        // generated.
        image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, 0, nullptr);
        EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
        EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);

        // If <target> is EGL_GL_TEXTURE_2D_KHR, EGL_GL_TEXTURE_CUBE_MAP_*_KHR, or
        // EGL_GL_TEXTURE_3D_KHR, and the value specified in <attr_list> for
        // EGL_GL_TEXTURE_LEVEL_KHR is not a valid mipmap level for the specified GL texture object
        // <buffer>, the error EGL_BAD_MATCH is generated.
        EGLint level2Attribute[] = {
            EGL_GL_TEXTURE_LEVEL_KHR,
            2,
            EGL_NONE,
        };
        image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
                                  reinterpretHelper<EGLClientBuffer>(incompleteTexture),
                                  level2Attribute);
        EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
        EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
    }
    else
    {
        GLTexture texture2D;
        glBindTexture(GL_TEXTURE_2D, texture2D);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

        // From EGL_KHR_image_base:
        // If <target> is not one of the values in Table aaa, the error EGL_BAD_PARAMETER is
        // generated.
        image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
                                  reinterpretHelper<EGLClientBuffer>(texture2D), nullptr);
        EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
        EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
    }

    if (hasCubemapExt())
    {
        // If EGL_GL_TEXTURE_LEVEL_KHR is 0, <target> is EGL_GL_TEXTURE_CUBE_MAP_*_KHR, <buffer> is
        // not the name of a complete GL texture object, and one or more faces do not have mipmap
        // level 0 specified, the error EGL_BAD_PARAMETER is generated.
        GLTexture incompleteTextureCube;
        glBindTexture(GL_TEXTURE_CUBE_MAP, incompleteTextureCube);
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     nullptr);
        glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     nullptr);
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     nullptr);
        glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     nullptr);
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     nullptr);

        EGLint level0Attribute[] = {
            EGL_GL_TEXTURE_LEVEL_KHR,
            0,
            EGL_NONE,
        };
        image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR,
                                  reinterpretHelper<EGLClientBuffer>(incompleteTextureCube),
                                  level0Attribute);
        EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
        EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
    }
    else
    {
        GLTexture textureCube;
        glBindTexture(GL_TEXTURE_CUBE_MAP, textureCube);
        for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
             face++)
        {
            glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
        }

        // From EGL_KHR_image_base:
        // If <target> is not one of the values in Table aaa, the error EGL_BAD_PARAMETER is
        // generated.
        image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR,
                                  reinterpretHelper<EGLClientBuffer>(textureCube), nullptr);
        EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
        EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
    }

    if (has3DTextureExt() && getClientMajorVersion() >= 3)
    {
        // If <target> is EGL_GL_TEXTURE_3D_KHR, and the value specified in <attr_list> for
        // EGL_GL_TEXTURE_ZOFFSET_KHR exceeds the depth of the specified mipmap level - of - detail
        // in <buffer>, the error EGL_BAD_PARAMETER is generated.
        GLTexture texture3D;
        glBindTexture(GL_TEXTURE_3D, texture3D);
        glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

        EGLint zOffset3Parameter[] = {
            EGL_GL_TEXTURE_ZOFFSET_KHR,
            3,
            EGL_NONE,
        };
        image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_3D_KHR,
                                  reinterpretHelper<EGLClientBuffer>(texture3D), zOffset3Parameter);
        EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
        EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);

        EGLint zOffsetNegative1Parameter[] = {
            EGL_GL_TEXTURE_ZOFFSET_KHR,
            -1,
            EGL_NONE,
        };
        image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_3D_KHR,
                                  reinterpretHelper<EGLClientBuffer>(texture3D),
                                  zOffsetNegative1Parameter);
        EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
        EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
    }
    else
    {
        if (has2DTextureExt())
        {
            GLTexture texture2D;
            glBindTexture(GL_TEXTURE_2D, texture2D);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

            // Verify EGL_GL_TEXTURE_ZOFFSET_KHR is not a valid parameter
            EGLint zOffset0Parameter[] = {
                EGL_GL_TEXTURE_ZOFFSET_KHR,
                0,
                EGL_NONE,
            };

            image =
                eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR,
                                  reinterpretHelper<EGLClientBuffer>(texture2D), zOffset0Parameter);
            EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
            EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
        }

        if (getClientMajorVersion() >= 3)
        {
            GLTexture texture3D;
            glBindTexture(GL_TEXTURE_3D, texture3D);
            glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

            // From EGL_KHR_image_base:
            // If <target> is not one of the values in Table aaa, the error EGL_BAD_PARAMETER is
            // generated.
            image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_3D_KHR,
                                      reinterpretHelper<EGLClientBuffer>(texture3D), nullptr);
            EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
            EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
        }
    }

    if (hasRenderbufferExt())
    {
        // If <target> is EGL_GL_RENDERBUFFER_KHR and <buffer> is not the name of a renderbuffer
        // object, or if <buffer> is the name of a multisampled renderbuffer object, the error
        // EGL_BAD_PARAMETER is generated.
        image = eglCreateImageKHR(display, context, EGL_GL_RENDERBUFFER_KHR,
                                  reinterpret_cast<EGLClientBuffer>(0), nullptr);
        EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
        EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);

        if (IsGLExtensionEnabled("GL_ANGLE_framebuffer_multisample"))
        {
            GLRenderbuffer renderbuffer;
            glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
            glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 1, GL_RGBA8, 1, 1);
            EXPECT_GL_NO_ERROR();

            image = eglCreateImageKHR(display, context, EGL_GL_RENDERBUFFER_KHR,
                                      reinterpret_cast<EGLClientBuffer>(0), nullptr);
            EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
            EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
        }
    }
    else
    {
        GLRenderbuffer renderbuffer;
        glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, 1, 1);

        // From EGL_KHR_image_base:
        // If <target> is not one of the values in Table aaa, the error EGL_BAD_PARAMETER is
        // generated.
        image = eglCreateImageKHR(display, context, EGL_GL_RENDERBUFFER_KHR,
                                  reinterpretHelper<EGLClientBuffer>(renderbuffer), nullptr);
        EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
        EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
    }
}

// Check validation from the GL_OES_EGL_image extension
TEST_P(ImageTest, ValidationGLEGLImage)
{
    ValidationGLEGLImage_helper(kDefaultAttribs);
}

TEST_P(ImageTest, ValidationGLEGLImage_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_sRGB"));
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    ValidationGLEGLImage_helper(kColorspaceAttribs);
}

void ImageTest::ValidationGLEGLImage_helper(const EGLint *attribs)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, attribs, kLinearColor, source,
                                  &image);

    // If <target> is not TEXTURE_2D, the error INVALID_ENUM is generated.
    glEGLImageTargetTexture2DOES(GL_TEXTURE_CUBE_MAP_POSITIVE_X, image);
    EXPECT_GL_ERROR(GL_INVALID_ENUM);

    // If <image> does not refer to a valid eglImageOES object, the error INVALID_VALUE is
    // generated.
    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, reinterpret_cast<GLeglImageOES>(0xBAADF00D));
    EXPECT_GL_ERROR(GL_INVALID_VALUE);

    // <target> must be RENDERBUFFER_OES, and <image> must be the handle of a valid EGLImage
    // resource, cast into the type
    // eglImageOES.
    glEGLImageTargetRenderbufferStorageOES(GL_TEXTURE_2D, image);
    EXPECT_GL_ERROR(GL_INVALID_ENUM);

    // If a renderbuffer is not bound, the error INVALID_OPERATION is generated.
    // (Not in specification.)
    glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, image);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    // If the GL is unable to create a renderbuffer using the specified eglImageOES, the error
    // INVALID_OPERATION is generated.If <image>
    // does not refer to a valid eglImageOES object, the error INVALID_VALUE is generated.
    GLRenderbuffer renderbuffer;
    glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
    glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER,
                                           reinterpret_cast<GLeglImageOES>(0xBAADF00D));
    EXPECT_GL_ERROR(GL_INVALID_VALUE);

    // Clean up
    eglDestroyImageKHR(getEGLWindow()->getDisplay(), image);
}

// Check validation from the GL_OES_EGL_image_external extension
TEST_P(ImageTest, ValidationGLEGLImageExternal)
{
    ANGLE_SKIP_TEST_IF(!hasExternalExt());

    GLTexture texture;
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);

    // In the initial state of a TEXTURE_EXTERNAL_OES texture object, the value assigned to
    // TEXTURE_MIN_FILTER and TEXTURE_MAG_FILTER is LINEAR, and the s and t wrap modes are both set
    // to CLAMP_TO_EDGE
    auto getTexParam = [](GLenum target, GLenum pname) {
        GLint value = 0;
        glGetTexParameteriv(target, pname, &value);
        EXPECT_GL_NO_ERROR();
        return value;
    };
    EXPECT_GLENUM_EQ(GL_LINEAR, getTexParam(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER));
    EXPECT_GLENUM_EQ(GL_LINEAR, getTexParam(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER));
    EXPECT_GLENUM_EQ(GL_CLAMP_TO_EDGE, getTexParam(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S));
    EXPECT_GLENUM_EQ(GL_CLAMP_TO_EDGE, getTexParam(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T));

    // "When <target> is TEXTURE_EXTERNAL_OES only NEAREST and LINEAR are accepted as
    // TEXTURE_MIN_FILTER, only CLAMP_TO_EDGE is accepted as TEXTURE_WRAP_S and TEXTURE_WRAP_T, and
    // only FALSE is accepted as GENERATE_MIPMAP. Attempting to set other values for
    // TEXTURE_MIN_FILTER, TEXTURE_WRAP_S, TEXTURE_WRAP_T, or GENERATE_MIPMAP will result in an
    // INVALID_ENUM error.
    GLenum validMinFilters[]{
        GL_NEAREST,
        GL_LINEAR,
    };
    for (auto minFilter : validMinFilters)
    {
        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, minFilter);
        EXPECT_GL_NO_ERROR();
    }

    GLenum invalidMinFilters[]{
        GL_NEAREST_MIPMAP_LINEAR,
        GL_NEAREST_MIPMAP_NEAREST,
        GL_LINEAR_MIPMAP_LINEAR,
        GL_LINEAR_MIPMAP_NEAREST,
    };
    for (auto minFilter : invalidMinFilters)
    {
        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, minFilter);
        EXPECT_GL_ERROR(GL_INVALID_ENUM);
    }

    GLenum validWrapModes[]{
        GL_CLAMP_TO_EDGE,
    };
    for (auto wrapMode : validWrapModes)
    {
        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, wrapMode);
        EXPECT_GL_NO_ERROR();
        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, wrapMode);
        EXPECT_GL_NO_ERROR();
    }

    if (IsGLExtensionEnabled("GL_EXT_EGL_image_external_wrap_modes"))
    {
        GLenum validWrapModesEXT[]{GL_REPEAT, GL_MIRRORED_REPEAT};
        for (auto wrapMode : validWrapModesEXT)
        {
            glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, wrapMode);
            EXPECT_GL_NO_ERROR();
            glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, wrapMode);
            EXPECT_GL_NO_ERROR();
        }
    }
    else
    {
        GLenum invalidWrapModes[]{
            GL_REPEAT,
            GL_MIRRORED_REPEAT,
        };
        for (auto wrapMode : invalidWrapModes)
        {
            glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, wrapMode);
            EXPECT_GL_ERROR(GL_INVALID_ENUM);
            glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, wrapMode);
            EXPECT_GL_ERROR(GL_INVALID_ENUM);
        }
    }

    // When <target> is set to TEXTURE_EXTERNAL_OES, GenerateMipmap always fails and generates an
    // INVALID_ENUM error.
    glGenerateMipmap(GL_TEXTURE_EXTERNAL_OES);
    EXPECT_GL_ERROR(GL_INVALID_ENUM);
}

// Check validation from the GL_OES_EGL_image_external_essl3 extension
TEST_P(ImageTest, ValidationGLEGLImageExternalESSL3)
{
    ANGLE_SKIP_TEST_IF(!hasExternalESSL3Ext());

    // Make sure this extension is not exposed without ES3.
    ASSERT_GE(getClientMajorVersion(), 3);

    GLTexture texture;
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);

    // It is an INVALID_OPERATION error to set the TEXTURE_BASE_LEVEL to a value other than zero.
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_BASE_LEVEL, 1);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_BASE_LEVEL, 10);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_BASE_LEVEL, 0);
    EXPECT_GL_NO_ERROR();
}

// Check validation from the GL_EXT_EGL_image_storage extension
TEST_P(ImageTest, ValidationGLEGLImageStorage)
{
    ANGLE_SKIP_TEST_IF(!hasEglImageStorageExt());

    // Make sure this extension is not exposed without ES3.
    ASSERT_GE(getClientMajorVersion(), 3);

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    // Create the Image
    GLTexture source2D;
    EGLImageKHR image2D;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs, kLinearColor,
                                  source2D, &image2D);

    // <target> must be one of GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D,
    // GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_ARRAY.  On OpenGL implementations
    // (non-ES), <target> can also be GL_TEXTURE_1D or GL_TEXTURE_1D_ARRAY.
    // If the implementation supports OES_EGL_image_external, <target> can be
    // GL_TEXTURE_EXTERNAL_OES
    glEGLImageTargetTexStorageEXT(GL_TEXTURE_CUBE_MAP_POSITIVE_X, image2D, nullptr);
    EXPECT_GL_ERROR(GL_INVALID_ENUM);

    // If <image> is NULL, the error INVALID_VALUE is generated.  If <image> is
    // neither NULL nor a valid value, the behavior is undefined, up to and
    // including program termination.
    glEGLImageTargetTexStorageEXT(GL_TEXTURE_2D, nullptr, nullptr);
    EXPECT_GL_ERROR(GL_INVALID_VALUE);

    // If the GL is unable to specify a texture object using the supplied
    // eglImageOES <image> the error INVALID_OPERATION is generated.
    glEGLImageTargetTexStorageEXT(GL_TEXTURE_3D, image2D, nullptr);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    GLint nonNullAttrib[1] = {GL_TEXTURE_2D};

    // If <attrib_list> is neither NULL nor a pointer to the value GL_NONE, the
    // error INVALID_VALUE is generated.
    glEGLImageTargetTexStorageEXT(GL_TEXTURE_2D, image2D, nonNullAttrib);
    EXPECT_GL_ERROR(GL_INVALID_VALUE);

    // Clean up
    eglDestroyImageKHR(getEGLWindow()->getDisplay(), image2D);
}

TEST_P(ImageTest, Source2DTarget2D)
{
    Source2DTarget2D_helper(kDefaultAttribs);
}

TEST_P(ImageTest, Source2DTarget2D_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_sRGB"));
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    Source2DTarget2D_helper(kColorspaceAttribs);
}

void ImageTest::Source2DTarget2D_helper(const EGLint *attribs)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, attribs,
                                  static_cast<void *>(kSrgbColor), source, &image);

    // Create the target
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Verify that the target texture has the expected color
    verifyResults2D(target, getExpected2DColorForAttribList(attribs));

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

void ImageTest::ImageStorageGenerateMipmap_helper(const EGLint *attribs,
                                                  const GLsizei width,
                                                  const GLsizei height,
                                                  AHardwareBuffer *srcAhb,
                                                  GLuint srcTexture,
                                                  EGLImageKHR *imageOut)
{
    ASSERT(srcAhb != nullptr || glIsTexture(srcTexture));

    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_sRGB"));
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasEglImageStorageExt());

    constexpr int kNumTiles = 8;
    const int tileWidth     = width / kNumTiles;
    const int tileHeight    = height / kNumTiles;

    // Create EGLImage and then a target texture from that image
    EGLWindow *window = getEGLWindow();
    if (srcAhb != nullptr)
    {
        *imageOut =
            eglCreateImageKHR(window->getDisplay(), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
                              angle::android::AHardwareBufferToClientBuffer(srcAhb), attribs);
    }
    else
    {
        *imageOut =
            eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
                              reinterpret_cast<EGLClientBuffer>(srcTexture), attribs);
    }
    ASSERT_EGL_SUCCESS();

    GLTexture dstTexture;
    glBindTexture(GL_TEXTURE_2D, dstTexture);
    // Setup for mipmapping
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    ASSERT_GL_NO_ERROR();

    glEGLImageTargetTexStorageEXT(GL_TEXTURE_2D, *imageOut, nullptr);
    ASSERT_GL_NO_ERROR();

    // Create framebuffer, attach level 0 of target texture and render pattern
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstTexture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    glEnable(GL_SCISSOR_TEST);
    for (int i = 0; i < kNumTiles; ++i)
    {
        for (int j = 0; j < kNumTiles; ++j)
        {
            const float v = (i & 1) ^ (j & 1) ? 0.5f : 0.f;
            glClearColor(v, 0.f, v, v);
            glScissor(i * tileWidth, j * tileHeight, tileWidth, tileHeight);
            glClear(GL_COLOR_BUFFER_BIT);
        }
    }
    glDisable(GL_SCISSOR_TEST);

    // Generate mipmap for target texture
    glGenerateMipmap(GL_TEXTURE_2D);
}

void ImageTest::verifyImageStorageMipmap(const EGLint *attribs,
                                         EGLImageKHR image,
                                         const GLsizei mipLevelCount)
{
    if (image == EGL_NO_IMAGE_KHR)
    {
        // Early return if image isn't valid
        return;
    }

    GLubyte linearColor[] = {64, 0, 64, 64};
    GLubyte srgbColor[]   = {137, 0, 137, 64};
    GLubyte *expectedColor =
        attribListHasSrgbColorspace(attribs, kColorspaceAttributeIndex) ? srgbColor : linearColor;

    GLTexture targetTexture;
    glBindTexture(GL_TEXTURE_2D, targetTexture);
    // Setup for mipmapping
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    ASSERT_GL_NO_ERROR();

    glEGLImageTargetTexStorageEXT(GL_TEXTURE_2D, image, nullptr);
    ASSERT_GL_NO_ERROR();

    // Create target framebuffer, attach "(mipLevelCount - 1)" level of target texture and verify
    // data
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, targetTexture,
                           mipLevelCount - 1);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    EXPECT_PIXEL_NEAR(0, 0, expectedColor[0], expectedColor[1], expectedColor[2], expectedColor[3],
                      1);

    // Verify that the target texture generates linear color when sampled
    glActiveTexture(GL_TEXTURE0);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glBindTexture(GL_TEXTURE_2D, targetTexture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, mipLevelCount - 1);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipLevelCount - 1);
    ASSERT_GL_NO_ERROR();

    verifyResults2D(targetTexture, linearColor);
}

void ImageTest::verifyImageStorageMipmapWithBlend(const EGLint *attribs,
                                                  EGLImageKHR image,
                                                  const GLsizei mipLevelCount)
{
    if (image == EGL_NO_IMAGE_KHR)
    {
        // Early return if image isn't valid
        return;
    }

    // Need to have at least miplevel 1
    ASSERT(mipLevelCount >= 1);
    // Verification used by only those tests with colorspace overrides
    ASSERT(attribListHasSrgbColorspace(attribs, kColorspaceAttributeIndex));

    GLTexture targetTexture;
    glBindTexture(GL_TEXTURE_2D, targetTexture);
    // Setup for mipmapping
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    ASSERT_GL_NO_ERROR();

    glEGLImageTargetTexStorageEXT(GL_TEXTURE_2D, image, nullptr);
    ASSERT_GL_NO_ERROR();

    // Create target framebuffer, attach mipLevel == 1 of target texture and verify
    // data with blending enabled.
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, targetTexture, 1);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Blend green color with contents of mipLevel 1
    // source color at (7, 11) of mipLevel 1 = [137, 0, 137, 64]
    GLubyte blendedColor[] = {137, 255, 137, 255};
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    glUseProgram(program);
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);

    EXPECT_PIXEL_NEAR(7, 11, blendedColor[0], blendedColor[1], blendedColor[2], blendedColor[3], 1);
}

void ImageTest::SourceAHBTarget2DImageStorageGenerateMipmap_helper(const EGLint *attribs)
{
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    constexpr GLsizei kWidth    = 40;
    constexpr GLsizei kHeight   = 32;
    constexpr GLsizei kDepth    = 1;
    const GLsizei mipLevelCount = static_cast<GLsizei>(std::log2(std::max(kWidth, kHeight)) + 1);

    ANGLE_SKIP_TEST_IF(!isAndroidHardwareBufferConfigurationSupported(
        kWidth, kHeight, kDepth, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
        kDefaultAHBUsage | kAHBUsageGPUMipMapComplete));

    // Create source AHB
    AHardwareBuffer *aHardwareBuffer =
        createAndroidHardwareBuffer(kWidth, kHeight, kDepth, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                    kDefaultAHBUsage | kAHBUsageGPUMipMapComplete, {});
    EXPECT_NE(aHardwareBuffer, nullptr);

    EGLImageKHR image = EGL_NO_IMAGE_KHR;
    ImageStorageGenerateMipmap_helper(attribs, kWidth, kHeight, aHardwareBuffer, 0, &image);
    verifyImageStorageMipmap(attribs, image, mipLevelCount);

    // Clean up image
    eglDestroyImageKHR(getEGLWindow()->getDisplay(), image);

    // Clean up AHB
    destroyAndroidHardwareBuffer(aHardwareBuffer);
}

// Test interaction between AHB, GL_EXT_EGL_image_storage and glGenerateMipmap
TEST_P(ImageTestES3, SourceAHBTarget2DGenerateMipmap)
{
    SourceAHBTarget2DImageStorageGenerateMipmap_helper(kDefaultAttribs);
}

// Test interaction between AHB, GL_EXT_EGL_image_storage and glGenerateMipmap with colorspace
// overrides This mirrors the SingleLayer_ColorTest_MipmapComplete_R8G8B8A8_UNORM_sRGB Android CTS
// test
TEST_P(ImageTestES3, SourceAHBTarget2DGenerateMipmap_Colorspace)
{
    SourceAHBTarget2DImageStorageGenerateMipmap_helper(kColorspaceAttribs);
}

// Test to ensure that Vulkan backend's LOAD_OP is correct for non-0 miplevels. A bug in
// content tracking of mip levels will cause rendering artifacts and result in test failure.
TEST_P(ImageTestES3, SourceAHBTarget2DGenerateMipmapColorspaceBlend)
{
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    constexpr GLsizei kWidth    = 40;
    constexpr GLsizei kHeight   = 32;
    constexpr GLsizei kDepth    = 1;
    const GLsizei mipLevelCount = static_cast<GLsizei>(std::log2(std::max(kWidth, kHeight)) + 1);

    ANGLE_SKIP_TEST_IF(!isAndroidHardwareBufferConfigurationSupported(
        kWidth, kHeight, kDepth, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
        kDefaultAHBUsage | kAHBUsageGPUMipMapComplete));

    // Create source AHB
    AHardwareBuffer *aHardwareBuffer =
        createAndroidHardwareBuffer(kWidth, kHeight, kDepth, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                    kDefaultAHBUsage | kAHBUsageGPUMipMapComplete, {});
    EXPECT_NE(aHardwareBuffer, nullptr);

    EGLImageKHR image = EGL_NO_IMAGE_KHR;
    ImageStorageGenerateMipmap_helper(kColorspaceAttribs, kWidth, kHeight, aHardwareBuffer, 0,
                                      &image);
    verifyImageStorageMipmapWithBlend(kColorspaceAttribs, image, mipLevelCount);

    // Clean up image
    eglDestroyImageKHR(getEGLWindow()->getDisplay(), image);

    // Clean up AHB
    destroyAndroidHardwareBuffer(aHardwareBuffer);
}

// Test interaction between AHB, GL_OES_EGL_image_external and glGenerateMipmap.
TEST_P(ImageTestES3, SourceAHBTargetTexture2DGenerateMipmap)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    GLubyte red_data[16] = {255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255};

    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(2, 2, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {{red_data, 16}},
                                              &source, &image);

    // Create a texture target to bind the egl image.
    GLTexture tex1;
    createEGLImageTargetTexture2D(image, tex1);

    // Draw to the tex1.
    GLFramebuffer fbo1;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex1, 0);
    ASSERT_GL_NO_ERROR();
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.0f);
    ASSERT_GL_NO_ERROR();

    // Generate mipmap for texture.
    glBindTexture(GL_TEXTURE_2D, tex1);
    glGenerateMipmap(GL_TEXTURE_2D);
    ASSERT_GL_NO_ERROR();

    // Attach the texture to fbo2.
    GLTexture tex2;
    glBindTexture(GL_TEXTURE_2D, tex2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    GLFramebuffer fbo2;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2, 0);
    ASSERT_GL_NO_ERROR();
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Sample tex1.
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glBindTexture(GL_TEXTURE_2D, tex1);
    ANGLE_GL_PROGRAM(drawTexture, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    glUseProgram(drawTexture);
    GLint texLocation = glGetUniformLocation(drawTexture, essl1_shaders::Texture2DUniform());
    ASSERT_NE(-1, texLocation);
    glUniform1i(texLocation, 0);
    drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.5f);

    // Verify results.
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    // Clean up.
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Test that drawing to an AHB works.
TEST_P(ImageTestES3, SourceAHBTarget2DDraw)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    // Create the Image without data so we don't need ANGLE_AHARDWARE_BUFFER_LOCK_PLANES_SUPPORT
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {}, &source,
                                              &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Draw to the target and verify results.
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.0f);
    ASSERT_GL_NO_ERROR();

    // Verify results for completeness.
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Test that using an image through a texture, detaching it, then using it again with another
// texture works.  This is similar to the usage pattern of |SourceAHBTarget2DGenerateMipmap|, but
// doesn't require the |kAHBUsageGPUMipMapComplete| flags.
TEST_P(ImageTestES3, SourceAHBTarget2DUseAfterDetach)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    // Create the Image without data so we don't need ANGLE_AHARDWARE_BUFFER_LOCK_PLANES_SUPPORT
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {}, &source,
                                              &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Clear the texture, use a temporary framebuffer.
    {
        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target, 0);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
        glClearColor(1, 0, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    }

    // Use the texture in a command buffer, but don't let it get submitted (use the default
    // framebuffer).
    ANGLE_GL_PROGRAM(drawTexture, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    GLint texLocation = glGetUniformLocation(drawTexture, essl1_shaders::Texture2DUniform());
    ASSERT_NE(-1, texLocation);
    glUseProgram(drawTexture);
    glUniform1i(texLocation, 0);
    ASSERT_GL_NO_ERROR();

    glBindTexture(GL_TEXTURE_2D, target);
    drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.5f);

    // Release the texture.  In the Vulkan backend, the image is scheduled to be transitioned to the
    // FORIENG queue because this is an AHB.
    glBindTexture(GL_TEXTURE_2D, 0);
    target.reset();

    // Now attach another texture to the same image.
    GLTexture target2;
    glBindTexture(GL_TEXTURE_2D, target2);
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
    ASSERT_GL_NO_ERROR();

    // Use the new texture.  In the Vulkan backend, the management of transfer to FOREIGN queue and
    // back should be correct.
    drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Verify results for completeness.
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Try to orphan image created with the GL_EXT_EGL_image_storage extension
TEST_P(ImageTestES3, Source2DTarget2DStorageOrphan)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasEglImageStorageExt());

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs,
                                  static_cast<void *>(&kLinearColor), source, &image);

    // Create the target
    GLTexture target;
    createEGLImageTargetTextureStorage(image, GL_TEXTURE_2D, target, nullptr);

    // Expect that the target texture has the same color as the source texture
    verifyResults2D(target, kLinearColor);

    // Try to orphan this target texture
    glBindTexture(GL_TEXTURE_2D, target);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, kLinearColor);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Try to orphan 3D image created with the GL_EXT_EGL_image_storage extension
TEST_P(ImageTestES3, Source3DTarget3DStorageOrphan)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has3DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasEglImageStorageExt());

    constexpr size_t depth = 2;
    EGLint attribs[3]      = {EGL_IMAGE_PRESERVED, EGL_TRUE, EGL_NONE};

    // Create the Image
    GLTexture source;
    EGLImageKHR image;

    createEGLImage3DTextureSource(1, 1, depth, GL_RGBA, GL_UNSIGNED_BYTE, attribs,
                                  static_cast<void *>(&kLinearColor3D), source, &image);

    // Create the target
    GLTexture target;
    createEGLImageTargetTextureStorage(image, GL_TEXTURE_3D, target, nullptr);

    for (size_t layer = 0; layer < depth; layer++)
    {
        // Expect that the target texture has the same color as the source texture
        verifyResults3D(target, &kLinearColor3D[layer * 4], layer, depth);
    }

    // Try to orphan this target texture
    glBindTexture(GL_TEXTURE_3D, target);
    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, depth, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 kLinearColor);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Create target texture from EGL image and then trigger texture respecification.
TEST_P(ImageTest, Source2DTarget2DTargetTextureRespecifyColorspace)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_format_sRGB_override"));

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs,
                                  static_cast<void *>(&kSrgbColor), source, &image);

    // Create the target
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Expect that the target texture has the same color as the source texture
    verifyResults2D(target, kSrgbColor);

    // Respecify texture colorspace and verify results
    glBindTexture(GL_TEXTURE_2D, target);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT, GL_SRGB);
    ASSERT_GL_NO_ERROR();
    // Expect that the target texture decodes the sRGB color to linear when sampling
    verifyResults2D(target, kLinearColor);

    // Reset texture parameter and verify results again
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT, GL_NONE);
    ASSERT_GL_NO_ERROR();
    // Expect that the target texture has the same color as the source texture
    verifyResults2D(target, kSrgbColor);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Create target texture from EGL image and then trigger texture respecification.
TEST_P(ImageTest, Source2DTarget2DTargetTextureRespecifySize)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs,
                                  static_cast<void *>(&kLinearColor), source, &image);

    // Create the target
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Expect that the target texture has the same color as the source texture
    verifyResults2D(target, kLinearColor);

    // Respecify texture size and verify results
    std::array<GLubyte, 16> referenceColor;
    referenceColor.fill(127);
    glBindTexture(GL_TEXTURE_2D, target);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 referenceColor.data());
    ASSERT_GL_NO_ERROR();

    // Expect that the target texture has the reference color values
    verifyResults2D(target, referenceColor.data());

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Create target texture from EGL image and then trigger texture respecification.
TEST_P(ImageTestES3, Source2DTarget2DTargetTextureRespecifyLevel)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs,
                                  static_cast<void *>(&kLinearColor), source, &image);

    // Create the target
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Expect that the target texture has the same color as the source texture
    verifyResults2D(target, kLinearColor);

    // Respecify texture levels and verify results
    glBindTexture(GL_TEXTURE_2D, target);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4);
    ASSERT_GL_NO_ERROR();

    // Expect that the target texture has the reference color values
    verifyResults2D(target, kLinearColor);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Test that drawing to an AHB with MSRTSS works.
TEST_P(ImageTestES3, SourceAHBTarget2DTextureThenMSRTSS)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));

    // Create the Image without data so we don't need ANGLE_AHARDWARE_BUFFER_LOCK_PLANES_SUPPORT
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {}, &source,
                                              &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Draw to the target and verify results.
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                         target, 0, 4);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.0f);
    ASSERT_GL_NO_ERROR();

    // Verify results for completeness.
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Create target texture from EGL image and then trigger texture respecification which releases the
// last image ref.
TEST_P(ImageTest, ImageOrphanRefCountingBug)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    // Create the first Image
    GLTexture source1;
    EGLImageKHR image1;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs,
                                  static_cast<void *>(&kLinearColor), source1, &image1);

    // Create the target
    GLTexture target;
    createEGLImageTargetTexture2D(image1, target);

    // Delete the source and image. A ref is still held by the target texture
    source1.reset();
    eglDestroyImageKHR(window->getDisplay(), image1);

    // Create the second Image
    GLTexture source2;
    EGLImageKHR image2;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs,
                                  static_cast<void *>(&kLinearColor), source2, &image2);

    // Respecify the target with the second image.
    glBindTexture(GL_TEXTURE_2D, target);
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image2);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image2);
}

// Testing source 2D texture, target 2D array texture
TEST_P(ImageTest, Source2DTarget2DArray)
{
    Source2DTarget2DArray_helper(kDefaultAttribs);
}

// Testing source 2D texture with colorspace, target 2D array texture
TEST_P(ImageTest, Source2DTarget2DArray_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_sRGB"));
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    Source2DTarget2DArray_helper(kColorspaceAttribs);
}

void ImageTest::Source2DTarget2DArray_helper(const EGLint *attribs)
{
    ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() ||
                       !hasEglImageArrayExt());

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, attribs, kSrgbColor, source,
                                  &image);

    // Create the target
    GLTexture target;
    createEGLImageTargetTexture2DArray(image, target);

    // Verify that the target texture has the expected color
    verifyResults2DArray(target, getExpected2DColorForAttribList(attribs));

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Testing source AHB EGL image, if the client buffer is null, the test will not crash
TEST_P(ImageTest, SourceAHBInvalid)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !IsVulkan());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    // Create the Image
    EGLImageKHR image = eglCreateImageKHR(window->getDisplay(), EGL_NO_CONTEXT,
                                          EGL_NATIVE_BUFFER_ANDROID, nullptr, nullptr);
    ASSERT_EGL_ERROR(EGL_BAD_PARAMETER);
    EXPECT_EQ(image, EGL_NO_IMAGE_KHR);
}

// Testing source AHB EGL image, if the client buffer is not a  ANativeWindowBuffer,
// eglCreateImageKHR should return NO_IMAGE and generate error EGL_BAD_PARAMETER.
TEST_P(ImageTest, SourceAHBCorrupt)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !IsVulkan());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
    EGLWindow *window = getEGLWindow();

    const AHardwareBuffer_Desc aHardwareBufferDescription = createAndroidHardwareBufferDesc(
        16, 16, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM, kAHBUsageGPUSampledImage);

    // Allocate memory from Android Hardware Buffer
    AHardwareBuffer *aHardwareBuffer = nullptr;
    EXPECT_EQ(0, AHardwareBuffer_allocate(&aHardwareBufferDescription, &aHardwareBuffer));

    std::memset(
        reinterpret_cast<void *>(angle::android::AHardwareBufferToClientBuffer(aHardwareBuffer)), 0,
        sizeof(int));
    EGLImageKHR ahbImage = eglCreateImageKHR(
        window->getDisplay(), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
        angle::android::AHardwareBufferToClientBuffer(aHardwareBuffer), kDefaultAttribs);

    ASSERT_EGL_ERROR(EGL_BAD_PARAMETER);
    EXPECT_EQ(ahbImage, EGL_NO_IMAGE_KHR);

    AHardwareBuffer_release(aHardwareBuffer);
#endif
}

// Helper function to check if it is reasonable to access texture resource
void ImageTest::ImageCheckingTextureAccessHelper(GLenum target, bool mipmap)
{
    constexpr GLsizei width = 2, height = 2, depth = 2;
    GLTexture source;
    EGLenum eglTarget;
    EGLWindow *window = getEGLWindow();

    glBindTexture(target, source);
    switch (target)
    {
        case GL_TEXTURE_2D:
            eglTarget = EGL_GL_TEXTURE_2D_KHR;
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                         nullptr);
            break;
        case GL_TEXTURE_3D:
            eglTarget = EGL_GL_TEXTURE_3D_KHR;
            glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, width, height, depth, 0, GL_RGBA,
                         GL_UNSIGNED_BYTE, nullptr);
            break;
        case GL_TEXTURE_CUBE_MAP:
            eglTarget = EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR;
            for (GLenum faceIdx = 0; faceIdx < 6; faceIdx++)
            {
                glTexImage2D(faceIdx + GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, width, height, 0,
                             GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
            }
            break;
        default:
            return;
    }

    if (mipmap)
    {
        glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        glGenerateMipmap(target);
    }

    EGLImageKHR image = eglCreateImageKHR(window->getDisplay(), window->getContext(), eglTarget,
                                          reinterpretHelper<EGLClientBuffer>(source), nullptr);
    ASSERT_EGL_SUCCESS();
    EXPECT_NE(image, EGL_NO_IMAGE_KHR);

    // If the texture is bound to egl image, EGL_BAD_ACCESS should be returned.
    EGLImageKHR invalidImage1 =
        eglCreateImageKHR(window->getDisplay(), window->getContext(), eglTarget,
                          reinterpretHelper<EGLClientBuffer>(source), nullptr);
    ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
    EXPECT_EQ(invalidImage1, EGL_NO_IMAGE_KHR);

    // If the image is destroyed, the texture could be bound to egl image here.
    eglDestroyImageKHR(window->getDisplay(), image);

    EGLImageKHR validImage1 =
        eglCreateImageKHR(window->getDisplay(), window->getContext(), eglTarget,
                          reinterpretHelper<EGLClientBuffer>(source), nullptr);
    ASSERT_EGL_SUCCESS();
    EXPECT_NE(validImage1, EGL_NO_IMAGE_KHR);

    if (target == GL_TEXTURE_3D)
    {
        constexpr EGLint zOffsetAttribs[] = {
            EGL_GL_TEXTURE_ZOFFSET,
            1,
            EGL_NONE,
        };
        EGLImageKHR validImage2 =
            eglCreateImageKHR(window->getDisplay(), window->getContext(), eglTarget,
                              reinterpretHelper<EGLClientBuffer>(source), zOffsetAttribs);
        ASSERT_EGL_SUCCESS();
        EXPECT_NE(validImage2, EGL_NO_IMAGE_KHR);
        eglDestroyImageKHR(window->getDisplay(), validImage2);
    }

    if (target == GL_TEXTURE_CUBE_MAP)
    {
        for (GLenum faceIdx = 1; faceIdx < 6; faceIdx++)
        {
            EGLImageKHR validImage2 =
                eglCreateImageKHR(window->getDisplay(), window->getContext(), eglTarget + faceIdx,
                                  reinterpretHelper<EGLClientBuffer>(source), nullptr);
            ASSERT_EGL_SUCCESS();
            EXPECT_NE(validImage2, EGL_NO_IMAGE_KHR);
            eglDestroyImageKHR(window->getDisplay(), validImage2);
        }
    }

    if (mipmap)
    {
        constexpr EGLint mipmapAttribs[] = {
            EGL_GL_TEXTURE_LEVEL,
            1,
            EGL_NONE,
        };
        EGLImageKHR validImage3 =
            eglCreateImageKHR(window->getDisplay(), window->getContext(), eglTarget,
                              reinterpretHelper<EGLClientBuffer>(source), mipmapAttribs);
        ASSERT_EGL_SUCCESS();
        EXPECT_NE(validImage3, EGL_NO_IMAGE_KHR);

        EGLImageKHR invalidImage2 =
            eglCreateImageKHR(window->getDisplay(), window->getContext(), eglTarget,
                              reinterpretHelper<EGLClientBuffer>(source), mipmapAttribs);
        ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
        EXPECT_EQ(invalidImage2, EGL_NO_IMAGE_KHR);

        eglDestroyImageKHR(window->getDisplay(), validImage3);
        EGLImageKHR validImage4 =
            eglCreateImageKHR(window->getDisplay(), window->getContext(), eglTarget,
                              reinterpretHelper<EGLClientBuffer>(source), mipmapAttribs);
        ASSERT_EGL_SUCCESS();
        EXPECT_NE(validImage4, EGL_NO_IMAGE_KHR);
        eglDestroyImageKHR(window->getDisplay(), validImage4);
    }

    eglDestroyImageKHR(window->getDisplay(), validImage1);
}

// Testing GLES resources when creating EGL image, if the client buffer itself is an EGL sibling,
// eglCreateImageKHR should return NO_IMAGE and generate error EGL_BAD_ACCESS.
TEST_P(ImageTest, SourceBadAccess)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !IsVulkan());

    // Validate gles 2D texture
    if (has2DTextureExt())
    {
        ImageCheckingTextureAccessHelper(GL_TEXTURE_2D, false);
        ImageCheckingTextureAccessHelper(GL_TEXTURE_2D, true);
    }

    // Validate gles 3D texture
    if (has3DTextureExt() && getClientMajorVersion() >= 3)
    {
        ImageCheckingTextureAccessHelper(GL_TEXTURE_3D, false);
        ImageCheckingTextureAccessHelper(GL_TEXTURE_3D, true);
    }

    // Validate gles cube map texture
    if (hasCubemapExt())
    {
        ImageCheckingTextureAccessHelper(GL_TEXTURE_CUBE_MAP, false);
        ImageCheckingTextureAccessHelper(GL_TEXTURE_CUBE_MAP, true);
    }

    // Validate gles renderbuffer
    if (hasRenderbufferExt())
    {
        EGLWindow *window = getEGLWindow();
        GLRenderbuffer source;
        EGLImageKHR image;
        createEGLImageRenderbufferSource(1, 1, GL_RGBA8_OES, kDefaultAttribs, source, &image);

        EGLImageKHR invalidImage =
            eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_RENDERBUFFER_KHR,
                              reinterpretHelper<EGLClientBuffer>(source), kDefaultAttribs);
        ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
        EXPECT_EQ(invalidImage, EGL_NO_IMAGE_KHR);
        eglDestroyImageKHR(window->getDisplay(), image);

        EGLImageKHR validImage =
            eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_RENDERBUFFER_KHR,
                              reinterpretHelper<EGLClientBuffer>(source), kDefaultAttribs);
        ASSERT_EGL_SUCCESS();
        EXPECT_NE(validImage, EGL_NO_IMAGE_KHR);
        eglDestroyImageKHR(window->getDisplay(), validImage);
    }
}

// Testing GLES resources when creating EGL image, if the client buffer itself is an EGL target,
// eglCreateImageKHR should return NO_IMAGE and generate error EGL_BAD_ACCESS.
TEST_P(ImageTest, ImageSiblingAsSourceTarget)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !IsVulkan() || !has2DTextureExt() ||
                       !hasRenderbufferExt());
    EGLWindow *window = getEGLWindow();

    // Validate gles texture
    GLRenderbuffer renderBufferSource;
    EGLImageKHR image1;
    createEGLImageRenderbufferSource(1, 1, GL_RGBA8_OES, kDefaultAttribs, renderBufferSource,
                                     &image1);
    GLTexture texture;
    createEGLImageTargetTexture2D(image1, texture);

    // Texture is both an EGL target and an EGL source. EGL_BAD_ACCESS should be returned
    EGLImageKHR invalidImage =
        eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D,
                          reinterpretHelper<EGLClientBuffer>(texture), kDefaultAttribs);
    ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
    EXPECT_EQ(invalidImage, EGL_NO_IMAGE_KHR);

    // Validate gles renderbuffer
    GLTexture textureSource;
    EGLImageKHR image2;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs,
                                  static_cast<void *>(&kLinearColor), textureSource, &image2);
    GLRenderbuffer renderBuffer;
    createEGLImageTargetRenderbuffer(image2, renderBuffer);

    // Renderbuffer is both an EGL target and an EGL source. EGL_BAD_ACCESS should be returned
    invalidImage =
        eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_RENDERBUFFER_KHR,
                          reinterpretHelper<EGLClientBuffer>(renderBuffer), kDefaultAttribs);
    ASSERT_EGL_ERROR(EGL_BAD_ACCESS);
    EXPECT_EQ(invalidImage, EGL_NO_IMAGE_KHR);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image1);
    eglDestroyImageKHR(window->getDisplay(), image2);
}

#if defined(ANGLE_ENABLE_WGPU)
// Testing source WebGPU Texture EGL image, target 2D texture
TEST_P(ImageTest, SourceWebGPUTextureTarget2D)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasWebGPUDeviceExt() || !hasWebGPUTextureExt());

    const DawnProcTable &wgpu = getWebGPUProcs();

    std::vector<GLubyte> data = {190, 128, 238, 255};
    uint32_t dataBytesPerRow  = 4;

    WGPUTextureDescriptor desc = WGPU_TEXTURE_DESCRIPTOR_INIT;
    desc.usage                 = WGPUTextureUsage_CopySrc | WGPUTextureUsage_CopyDst |
                 WGPUTextureUsage_RenderAttachment | WGPUTextureUsage_TextureBinding;
    desc.dimension = WGPUTextureDimension_2D;
    desc.size      = {1, 1, 1};
    desc.format    = WGPUTextureFormat_RGBA8Unorm;

    const EGLint attribs[] = {EGL_NONE};

    // Create the Image
    WGPUTexture source;
    EGLImageKHR image;
    createEGLImageWebGPUTextureClientBufferSource(desc, attribs, data, dataBytesPerRow, &source,
                                                  &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Use texture target bound to egl image as source and render to framebuffer
    // Verify that the target texture has the expected color
    verifyResults2D(target, getExpected2DColorForAttribList(attribs));

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    wgpu.textureRelease(source);
}

// Testing source WebGPU Texture EGL image, target 2D renderbuffer
TEST_P(ImageTest, SourceWebGPUTextureRenderbuffer)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasWebGPUDeviceExt() || !hasWebGPUTextureExt());

    const DawnProcTable &wgpu = getWebGPUProcs();

    std::vector<GLubyte> data = {190, 128, 238, 255};
    uint32_t dataBytesPerRow  = 4;

    WGPUTextureDescriptor desc = WGPU_TEXTURE_DESCRIPTOR_INIT;
    desc.usage                 = WGPUTextureUsage_CopySrc | WGPUTextureUsage_CopyDst |
                 WGPUTextureUsage_RenderAttachment | WGPUTextureUsage_TextureBinding;
    desc.dimension = WGPUTextureDimension_2D;
    desc.size      = {1, 1, 1};
    desc.format    = WGPUTextureFormat_RGBA8Unorm;

    const EGLint attribs[] = {EGL_NONE};

    // Create the Image
    WGPUTexture source;
    EGLImageKHR image;
    createEGLImageWebGPUTextureClientBufferSource(desc, attribs, data, dataBytesPerRow, &source,
                                                  &image);

    // Create a renderbuffer target to bind the egl image
    GLRenderbuffer target;
    createEGLImageTargetRenderbuffer(image, target);

    // Use renderbuffer target bound to egl image as source and render to framebuffer
    // Verify that the target renderbuffer has the expected color
    verifyResultsRenderbuffer(target, getExpected2DColorForAttribList(attribs));

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    wgpu.textureRelease(source);
}
#endif  // defined(ANGLE_ENABLE_WGPU)

// Testing source AHB EGL image, target 2D texture and delete when in use
// If refcounted correctly, the test should pass without issues
TEST_P(ImageTest, SourceAHBTarget2DEarlyDelete)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    GLubyte data[4] = {7, 51, 197, 231};

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {{data, 4}},
                                              &source, &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Delete the source AHB when in use
    destroyAndroidHardwareBuffer(source);

    // Use texture target bound to egl image as source and render to framebuffer
    // Verify that data in framebuffer matches that in the egl image
    verifyResults2D(target, data);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Testing source AHB EGL image, target 2D texture
TEST_P(ImageTest, SourceAHBTarget2D)
{
    SourceAHBTarget2D_helper(kDefaultAttribs);
}

// Testing source AHB EGL image with colorspace, target 2D texture
TEST_P(ImageTest, SourceAHBTarget2D_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_sRGB"));
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    SourceAHBTarget2D_helper(kColorspaceAttribs);
}

void ImageTest::SourceAHBTarget2D_helper(const EGLint *attribs)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, attribs, {{kSrgbColor, 4}}, &source,
                                              &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Use texture target bound to egl image as source and render to framebuffer
    // Verify that the target texture has the expected color
    verifyResults2D(target, getExpected2DColorForAttribList(attribs));

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Testing source AHB EGL images, target 2D external texture, cycling through YUV sources.
TEST_P(ImageTest, SourceAHBTarget2DExternalCycleThroughYuvSourcesNoData)
{
    // http://issuetracker.google.com/175021871
    ANGLE_SKIP_TEST_IF(IsPixel2() || IsPixel2XL());

    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    // Create YCbCr source and image but without initial data
    AHardwareBuffer *ycbcrSource;
    EGLImageKHR ycbcrImage;
    createEGLImageAndroidHardwareBufferSource(2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420,
                                              kDefaultAHBYUVUsage, kDefaultAttribs, {},
                                              &ycbcrSource, &ycbcrImage);
    EXPECT_NE(ycbcrSource, nullptr);
    EXPECT_NE(ycbcrImage, EGL_NO_IMAGE_KHR);

    // Create YCrCb source and image but without initial data
    AHardwareBuffer *ycrcbSource;
    EGLImageKHR ycrcbImage;
    createEGLImageAndroidHardwareBufferSource(2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cr8Cb8_420_SP,
                                              kDefaultAHBYUVUsage, kDefaultAttribs, {},
                                              &ycrcbSource, &ycrcbImage);
    EXPECT_NE(ycrcbSource, nullptr);
    EXPECT_NE(ycrcbImage, EGL_NO_IMAGE_KHR);

    // Create YV12 source and image but without initial data
    AHardwareBuffer *yv12Source;
    EGLImageKHR yv12Image;
    createEGLImageAndroidHardwareBufferSource(2, 2, 1, AHARDWAREBUFFER_FORMAT_YV12,
                                              kDefaultAHBYUVUsage, kDefaultAttribs, {}, &yv12Source,
                                              &yv12Image);
    EXPECT_NE(yv12Source, nullptr);
    EXPECT_NE(yv12Image, EGL_NO_IMAGE_KHR);

    // Create a texture target to bind the egl image
    GLTexture target;
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, target);
    // Disable mipmapping
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    ASSERT_GL_NO_ERROR();

    // Bind YCbCr image
    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, ycbcrImage);
    // Draw while sampling should result in no EGL/GL errors
    glUseProgram(mTextureExternalProgram);
    glUniform1i(mTextureExternalUniformLocation, 0);
    drawQuad(mTextureExternalProgram, "position", 0.5f);
    ASSERT_GL_NO_ERROR();

    // Bind YCrCb image
    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, ycrcbImage);
    // Draw while sampling should result in no EGL/GL errors
    glUseProgram(mTextureExternalProgram);
    glUniform1i(mTextureExternalUniformLocation, 0);
    drawQuad(mTextureExternalProgram, "position", 0.5f);
    ASSERT_GL_NO_ERROR();

    // Bind YV12 image
    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, yv12Image);
    // Draw while sampling should result in no EGL/GL errors
    glUseProgram(mTextureExternalProgram);
    glUniform1i(mTextureExternalUniformLocation, 0);
    drawQuad(mTextureExternalProgram, "position", 0.5f);
    ASSERT_GL_NO_ERROR();

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ycbcrImage);
    destroyAndroidHardwareBuffer(ycbcrSource);
    eglDestroyImageKHR(window->getDisplay(), ycrcbImage);
    destroyAndroidHardwareBuffer(ycrcbSource);
    eglDestroyImageKHR(window->getDisplay(), yv12Image);
    destroyAndroidHardwareBuffer(yv12Source);
}

// Testing source AHB EGL images, target 2D external texture, cycling through RGB and YUV sources.
TEST_P(ImageTest, SourceAHBTarget2DExternalCycleThroughRgbAndYuvSources)
{
    // http://issuetracker.google.com/175021871
    ANGLE_SKIP_TEST_IF(IsPixel2() || IsPixel2XL());

    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    ANGLE_SKIP_TEST_IF(!isAndroidHardwareBufferConfigurationSupported(
        1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, kDefaultAHBUsage));
    ANGLE_SKIP_TEST_IF(!isAndroidHardwareBufferConfigurationSupported(
        2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420, kDefaultAHBYUVUsage));

    // Create RGB Image
    AHardwareBuffer *rgbSource;
    EGLImageKHR rgbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs,
                                              {{GLColor::blue.data(), 4}}, &rgbSource, &rgbImage);

    // Create YUV Image
    AHardwareBuffer *yuvSource;
    EGLImageKHR yuvImage;
    createEGLImageAndroidHardwareBufferSource(
        2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420, kDefaultAHBYUVUsage, kDefaultAttribs,
        {{kYUVColorPurpleY, 1}, {kYUVColorPurpleCb, 1}, {kYUVColorPurpleCr, 1}}, &yuvSource,
        &yuvImage);

    // Create a texture target to bind the egl image
    GLTexture target;
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, target);
    // Disable mipmapping
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    ASSERT_GL_NO_ERROR();

    // Expected purple color in RGB colorspace
    constexpr GLColor kRGBColorPurple = GLColor(200u, 64u, 255u, 255u);

    // Bind YUV image
    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, yuvImage);
    // Expect render target to have the same color as yuvImage
    verifyResultsExternal(target, kRGBColorPurple.data());

    // Bind RGB image
    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, rgbImage);
    // Expect render target to have the same color as rgbImage
    verifyResultsExternal(target, GLColor::blue.data());

    // Bind YUV image
    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, yuvImage);
    // Expect render target to have the same color as yuvImage
    verifyResultsExternal(target, kRGBColorPurple.data());

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), yuvImage);
    destroyAndroidHardwareBuffer(yuvSource);
    eglDestroyImageKHR(window->getDisplay(), rgbImage);
    destroyAndroidHardwareBuffer(rgbSource);
}

// Testing source AHB EGL images, target 2D external textures, cycling through RGB and YUV targets.
TEST_P(ImageTest, SourceAHBTarget2DExternalCycleThroughRgbAndYuvTargets)
{
    // http://issuetracker.google.com/175021871
    ANGLE_SKIP_TEST_IF(IsPixel2() || IsPixel2XL());

    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Create RGBA Image
    AHardwareBuffer *rgbaSource;
    EGLImageKHR rgbaImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs,
                                              {{GLColor::blue.data(), 4}}, &rgbaSource, &rgbaImage);

    // Create YUV Image
    AHardwareBuffer *yuvSource;
    EGLImageKHR yuvImage;
    createEGLImageAndroidHardwareBufferSource(
        2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420, kDefaultAHBYUVUsage, kDefaultAttribs,
        {{kYUVColorPurpleY, 1}, {kYUVColorPurpleCb, 1}, {kYUVColorPurpleCr, 1}}, &yuvSource,
        &yuvImage);

    // Create texture target siblings to bind the egl images
    // Create YUV target and bind the image
    GLTexture yuvTarget;
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, yuvTarget);
    // Disable mipmapping
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    ASSERT_GL_NO_ERROR();
    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, yuvImage);
    ASSERT_GL_NO_ERROR();

    // Create RGBA target and bind the image
    GLTexture rgbaTarget;
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, rgbaTarget);
    // Disable mipmapping
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    ASSERT_GL_NO_ERROR();
    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, rgbaImage);
    ASSERT_GL_NO_ERROR();

    // Expected purple color in RGB colorspace
    constexpr GLColor kRGBColorPurple = GLColor(200u, 64u, 255u, 255u);

    // Cycle through targets
    // YUV target
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, yuvTarget);
    // Expect render target to have the same color as yuvImage
    verifyResultsExternal(yuvTarget, kRGBColorPurple.data());

    // RGBA target
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, rgbaTarget);
    // Expect render target to have the same color as rgbaImage
    verifyResultsExternal(rgbaTarget, GLColor::blue.data());

    // YUV target
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, yuvTarget);
    // Expect render target to have the same color as yuvImage
    verifyResultsExternal(yuvTarget, kRGBColorPurple.data());

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), yuvImage);
    destroyAndroidHardwareBuffer(yuvSource);
    eglDestroyImageKHR(window->getDisplay(), rgbaImage);
    destroyAndroidHardwareBuffer(rgbaSource);
}

// Testing source AHB EGL images, target 2D external textures, cycling through YUV targets.
TEST_P(ImageTest, SourceAHBTarget2DExternalCycleThroughYuvTargetsNoData)
{
    // http://issuetracker.google.com/175021871
    ANGLE_SKIP_TEST_IF(IsPixel2() || IsPixel2XL());

    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    // Create YCbCr source and image but without initial data
    AHardwareBuffer *ycbcrSource;
    EGLImageKHR ycbcrImage;
    createEGLImageAndroidHardwareBufferSource(2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420,
                                              kDefaultAHBYUVUsage, kDefaultAttribs, {},
                                              &ycbcrSource, &ycbcrImage);
    EXPECT_NE(ycbcrSource, nullptr);
    EXPECT_NE(ycbcrImage, EGL_NO_IMAGE_KHR);

    // Create YV12 source and image but without initial data
    AHardwareBuffer *yv12Source;
    EGLImageKHR yv12Image;
    createEGLImageAndroidHardwareBufferSource(2, 2, 1, AHARDWAREBUFFER_FORMAT_YV12,
                                              kDefaultAHBYUVUsage, kDefaultAttribs, {}, &yv12Source,
                                              &yv12Image);
    EXPECT_NE(yv12Source, nullptr);
    EXPECT_NE(yv12Image, EGL_NO_IMAGE_KHR);

    // Create texture target siblings to bind the egl images
    // Create YCbCr target and bind the image
    GLTexture ycbcrTarget;
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, ycbcrTarget);
    // Disable mipmapping
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    ASSERT_GL_NO_ERROR();
    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, ycbcrImage);
    ASSERT_GL_NO_ERROR();

    // Create YV12 target and bind the image
    GLTexture yv12Target;
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, yv12Target);
    // Disable mipmapping
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    ASSERT_GL_NO_ERROR();
    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, yv12Image);
    ASSERT_GL_NO_ERROR();

    // Cycle through targets
    glUseProgram(mTextureExternalProgram);
    glUniform1i(mTextureExternalUniformLocation, 0);

    // Bind YCbCr image
    // YCbCr target
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, ycbcrTarget);
    // Draw while sampling should result in no EGL/GL errors
    drawQuad(mTextureExternalProgram, "position", 0.5f);
    ASSERT_GL_NO_ERROR();

    // YV12 target
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, yv12Target);
    // Draw while sampling should result in no EGL/GL errors
    drawQuad(mTextureExternalProgram, "position", 0.5f);
    ASSERT_GL_NO_ERROR();

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ycbcrImage);
    destroyAndroidHardwareBuffer(ycbcrSource);
    eglDestroyImageKHR(window->getDisplay(), yv12Image);
    destroyAndroidHardwareBuffer(yv12Source);
}

// Testing source AHB EGL image, target 2D texture retaining initial data.
TEST_P(ImageTest, SourceAHBTarget2DRetainInitialData)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    GLubyte data[4] = {0, 255, 0, 255};

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {{data, 4}},
                                              &source, &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Create a framebuffer, and blend into the texture.
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Blend into the framebuffer.
    ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.0f);
    ASSERT_GL_NO_ERROR();

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glDisable(GL_BLEND);

    // Use texture target bound to egl image as source and render to framebuffer
    // Verify that data in framebuffer matches that in the egl image
    GLubyte expect[4] = {255, 255, 0, 255};
    verifyResults2D(target, expect);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Test interaction between AHBs and GL_EXT_multisampled_render_to_texture
TEST_P(ImageTest, SourceAHBTarget2DMSRTTInteraction)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {}, &source,
                                              &image);

    // Create the target
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Bind target texture to mulisampled framebuffer
    GLFramebuffer fboMS;
    glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
    glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                         target, 0, 4);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Clear framebuffer
    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    // Check clear result
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);

    // Check the AHB is updated
    verifyResultAHB(source, {{GLColor::blue.data(), 4}});

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}
// Testing source AHB EGL image, target 2D array texture
TEST_P(ImageTest, SourceAHBTarget2DArray)
{
    SourceAHBTarget2DArray_helper(kDefaultAttribs);
}

// Testing source AHB EGL image with colorspace, target 2D array texture
TEST_P(ImageTest, SourceAHBTarget2DArray_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_sRGB"));
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    SourceAHBTarget2DArray_helper(kColorspaceAttribs);
}

void ImageTest::SourceAHBTarget2DArray_helper(const EGLint *attribs)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() ||
                       !hasEglImageArrayExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, attribs, {{kSrgbColor, 4}}, &source,
                                              &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTexture2DArray(image, target);

    // Use texture target bound to egl image as source and render to framebuffer
    // Verify that the target texture has the expected color
    verifyResults2DArray(target, getExpected2DColorForAttribList(attribs));

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Testing source AHB EGL image, target external texture
TEST_P(ImageTest, SourceAHBTargetExternal)
{
    SourceAHBTargetExternal_helper(kDefaultAttribs);
}

// Testing source AHB EGL image with colorspace, target external texture
TEST_P(ImageTest, SourceAHBTargetExternal_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_sRGB"));
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    SourceAHBTargetExternal_helper(kColorspaceAttribs);
}

void ImageTest::SourceAHBTargetExternal_helper(const EGLint *attribs)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() || !hasExternalExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Ozone only supports external target for images created with EGL_EXT_image_dma_buf_import
    ANGLE_SKIP_TEST_IF(IsOzone());

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, attribs, {{kSrgbColor, 4}}, &source,
                                              &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    // Use texture target bound to egl image as source and render to framebuffer
    // Verify that the target texture has the expected color
    verifyResultsExternal(target, getExpected2DColorForAttribList(attribs));

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Testing source AHB EGL image, target external ESSL3 texture
TEST_P(ImageTestES3, SourceAHBTargetExternalESSL3)
{
    SourceAHBTargetExternalESSL3_helper(kDefaultAttribs);
}

// Test sampling from a YUV texture using GL_ANGLE_yuv_internal_format as external texture and then
// switching to raw YUV sampling using EXT_yuv_target
TEST_P(ImageTestES3, SourceYUVTextureTargetExternalRGBSampleYUVSample)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() ||
                       !hasYUVInternalFormatExt() || !hasYUVTargetExt());

    // Create source YUV texture
    GLTexture yuvTexture;
    GLubyte yuvColor[6]         = {7, 51, 197, 231, 128, 192};
    GLubyte expectedRgbColor[4] = {255, 159, 211, 255};
    constexpr size_t kWidth     = 2;
    constexpr size_t kHeight    = 2;

    glBindTexture(GL_TEXTURE_2D, yuvTexture);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, kWidth, kHeight);
    ASSERT_GL_NO_ERROR();
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
                    GL_UNSIGNED_BYTE, yuvColor);
    ASSERT_GL_NO_ERROR();
    // Disable mipmapping
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    ASSERT_GL_NO_ERROR();

    // Create the Image
    EGLWindow *window = getEGLWindow();
    EGLImageKHR image =
        eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
                          reinterpretHelper<EGLClientBuffer>(yuvTexture), kDefaultAttribs);
    ASSERT_EGL_SUCCESS();

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    // Draw quad with program that samples YUV data with implicit RGB conversion
    glUseProgram(mTextureExternalProgram);
    glUniform1i(mTextureExternalUniformLocation, 0);
    drawQuad(mTextureExternalProgram, "position", 0.5f);
    // Expect that the rendered quad's color is converted to RGB
    EXPECT_PIXEL_NEAR(0, 0, expectedRgbColor[0], expectedRgbColor[1], expectedRgbColor[2],
                      expectedRgbColor[3], 1);

    // Draw quad with program that samples raw YUV data
    glUseProgram(mTextureYUVProgram);
    glUniform1i(mTextureYUVUniformLocation, 0);
    drawQuad(mTextureYUVProgram, "position", 0.5f);
    // Expect that the rendered quad's color matches the raw YUV data
    EXPECT_PIXEL_NEAR(0, 0, yuvColor[2], yuvColor[4], yuvColor[5], 255, 1);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Similar to SourceYUVTextureTargetExternalRGBSampleYUVSample, but added swizzle after
// __samplerExternal2DY2YEXT from texture.
TEST_P(ImageTestES3, SourceYUVTextureTargetExternalRGBSampleYUVSampleWithSwizzle)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() ||
                       !hasYUVInternalFormatExt() || !hasYUVTargetExt());

    // Create source YUV texture
    GLTexture yuvTexture;
    GLubyte yuvColor[6]      = {7, 51, 197, 231, 128, 192};
    constexpr size_t kWidth  = 2;
    constexpr size_t kHeight = 2;

    glBindTexture(GL_TEXTURE_2D, yuvTexture);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, kWidth, kHeight);
    ASSERT_GL_NO_ERROR();
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
                    GL_UNSIGNED_BYTE, yuvColor);
    ASSERT_GL_NO_ERROR();
    // Disable mipmapping
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    ASSERT_GL_NO_ERROR();

    // Create the Image
    EGLWindow *window = getEGLWindow();
    EGLImageKHR image =
        eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
                          reinterpretHelper<EGLClientBuffer>(yuvTexture), kDefaultAttribs);
    ASSERT_EGL_SUCCESS();

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    // Draw quad with program that samples raw YUV data and then swizzle
    const char *fragmentShaderSource = R"(#version 300 es
#extension GL_EXT_YUV_target : require
precision highp float;
uniform __samplerExternal2DY2YEXT tex;
in vec2 texcoord;
out vec4 color;

void main()
{
    color = vec4(texture(tex, texcoord).zyx, 1.0);
})";
    ANGLE_GL_PROGRAM(textureYUVProgram, getVSESSL3(), fragmentShaderSource);
    ASSERT_NE(0u, textureYUVProgram) << "shader compilation failed.";
    glUseProgram(textureYUVProgram);
    GLint uniformLocation = glGetUniformLocation(textureYUVProgram, "tex");
    ASSERT_NE(-1, uniformLocation);
    glUniform1i(uniformLocation, 0);
    drawQuad(textureYUVProgram, "position", 0.5f);
    // Expect that the rendered quad's color matches the raw YUV data after component swizzle
    EXPECT_PIXEL_NEAR(0, 0, yuvColor[5], yuvColor[4], yuvColor[2], 255, 1);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Test interaction between GL_ANGLE_yuv_internal_format and EXT_yuv_target when a program has
// both __samplerExternal2DY2YEXT and samplerExternalOES samplers.
TEST_P(ImageTestES3, ProgramWithBothExternalY2YAndExternalOESSampler)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() ||
                       !hasYUVInternalFormatExt() || !hasYUVTargetExt());

    GLubyte yuvColor[6]         = {40, 40, 40, 40, 240, 109};
    GLubyte expectedRgbColor[4] = {0, 0, 255, 255};
    constexpr size_t kWidth     = 2;
    constexpr size_t kHeight    = 2;

    // Create 2 plane YUV texture source
    GLTexture yuvTexture0;
    glBindTexture(GL_TEXTURE_2D, yuvTexture0);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, kWidth, kHeight);
    ASSERT_GL_NO_ERROR();
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
                    GL_UNSIGNED_BYTE, yuvColor);
    ASSERT_GL_NO_ERROR();
    // Disable mipmapping
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    ASSERT_GL_NO_ERROR();

    // Create 2 plane YUV texture source
    GLTexture yuvTexture1;
    glBindTexture(GL_TEXTURE_2D, yuvTexture1);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, kWidth, kHeight);
    ASSERT_GL_NO_ERROR();
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
                    GL_UNSIGNED_BYTE, yuvColor);
    ASSERT_GL_NO_ERROR();
    // Disable mipmapping
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    ASSERT_GL_NO_ERROR();

    // Create the Images
    EGLWindow *window = getEGLWindow();
    EGLImageKHR image0 =
        eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
                          reinterpretHelper<EGLClientBuffer>(yuvTexture0), kDefaultAttribs);
    ASSERT_EGL_SUCCESS();

    EGLImageKHR image1 =
        eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
                          reinterpretHelper<EGLClientBuffer>(yuvTexture1), kDefaultAttribs);
    ASSERT_EGL_SUCCESS();

    // Create texture targets for EGLImages
    GLTexture target0;
    createEGLImageTargetTextureExternal(image0, target0);

    GLTexture target1;
    createEGLImageTargetTextureExternal(image1, target1);

    // Create program with 2 samplers
    const char *vertexShaderSource   = R"(#version 300 es
out vec2 texcoord;
in vec4 position;
void main()
{
    gl_Position = vec4(position.xy, 0.0, 1.0);
    texcoord = (position.xy * 0.5) + 0.5;
})";
    const char *fragmentShaderSource = R"(#version 300 es
#extension GL_EXT_YUV_target : require
#extension GL_OES_EGL_image_external_essl3 : require
precision highp float;
uniform __samplerExternal2DY2YEXT tex0;
uniform samplerExternalOES tex1;
uniform uint samplerSelector;
in vec2 texcoord;
out vec4 fragColor;

void main()
{
    vec4 color0 = texture(tex0, texcoord);
    vec4 color1 = texture(tex1, texcoord);
    if (samplerSelector == 0u)
    {
        fragColor = color0;
    }
    else if (samplerSelector == 1u)
    {
        fragColor = color1;
    }
    else
    {
        fragColor = vec4(1.0);
    }
})";

    ANGLE_GL_PROGRAM(twoSamplersProgram, vertexShaderSource, fragmentShaderSource);
    glUseProgram(twoSamplersProgram);
    GLint tex0Location = glGetUniformLocation(twoSamplersProgram, "tex0");
    ASSERT_NE(-1, tex0Location);
    GLint tex1Location = glGetUniformLocation(twoSamplersProgram, "tex1");
    ASSERT_NE(-1, tex1Location);
    GLint samplerSelectorLocation = glGetUniformLocation(twoSamplersProgram, "samplerSelector");
    ASSERT_NE(-1, samplerSelectorLocation);

    // Bind texture target to GL_TEXTURE_EXTERNAL_OES
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, target0);
    ASSERT_GL_NO_ERROR();

    // Bind texture target to GL_TEXTURE_EXTERNAL_OES
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, target1);
    ASSERT_GL_NO_ERROR();

    // Set sampler uniform values
    glUniform1i(tex0Location, 0);
    glUniform1i(tex1Location, 1);

    // Set sampler selector uniform value and draw
    glUniform1ui(samplerSelectorLocation, 0);
    drawQuad(twoSamplersProgram, "position", 0.5f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_NEAR(0, 0, yuvColor[3], yuvColor[4], yuvColor[5], 255, 1);

    // Switch sampler selector uniform value and draw
    glUniform1ui(samplerSelectorLocation, 1);
    drawQuad(twoSamplersProgram, "position", 0.5f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_NEAR(0, 0, expectedRgbColor[0], expectedRgbColor[1], expectedRgbColor[2],
                      expectedRgbColor[3], 1);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image0);
    eglDestroyImageKHR(window->getDisplay(), image1);
}

// Test sampling from a YUV AHB with a regular external sampler and pre-initialized data
TEST_P(ImageTest, SourceYUVAHBTargetExternalRGBSampleInitData)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    // http://issuetracker.google.com/175021871
    ANGLE_SKIP_TEST_IF(IsPixel2() || IsPixel2XL());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(
        2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420, kDefaultAHBYUVUsage, kDefaultAttribs,
        {{kYUVColorRedY, 1}, {kYUVColorRedCb, 1}, {kYUVColorRedCr, 1}}, &source, &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    verifyResultsExternal(target, GLColor::red.data());

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Test sampling from a YUV AHB with a regular external sampler without data. This gives coverage of
// sampling even if we can't verify the results.
TEST_P(ImageTest, SourceYUVAHBTargetExternalRGBSampleNoData)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    // Create the Image without data so we don't need ANGLE_AHARDWARE_BUFFER_LOCK_PLANES_SUPPORT
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420,
                                              kDefaultAHBYUVUsage, kDefaultAttribs, {}, &source,
                                              &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    glUseProgram(mTextureExternalProgram);
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, target);
    glUniform1i(mTextureExternalUniformLocation, 0);

    // Sample from the YUV texture with a nearest sampler
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    drawQuad(mTextureExternalProgram, "position", 0.5f);

    // Sample from the YUV texture with a linear sampler
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    drawQuad(mTextureExternalProgram, "position", 0.5f);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Test sampling from a YUV AHB using EXT_yuv_target
TEST_P(ImageTestES3, SourceYUVAHBTargetExternalYUVSample)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() || !hasYUVTargetExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(
        2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420, kDefaultAHBYUVUsage, kDefaultAttribs,
        {{kYUVColorRedY, 1}, {kYUVColorRedCb, 1}, {kYUVColorRedCr, 1}}, &source, &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    GLubyte pixelColor[4] = {kYUVColorRedY[0], kYUVColorRedCb[0], kYUVColorRedCr[0], 255};
    verifyResultsExternalYUV(target, pixelColor);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Test sampling from a YUV AHB using EXT_yuv_target in the vertex shader
TEST_P(ImageTestES3, SourceYUVAHBTargetExternalYUVSampleVS)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() || !hasYUVTargetExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(
        2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420, kDefaultAHBYUVUsage, kDefaultAttribs,
        {{kYUVColorRedY, 1}, {kYUVColorRedCb, 1}, {kYUVColorRedCr, 1}}, &source, &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    GLubyte pixelColor[4] = {kYUVColorRedY[0], kYUVColorRedCb[0], kYUVColorRedCr[0], 255};
    verifyResultsExternalYUVVS(target, pixelColor);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Test texelFetch from a YUV AHB using samplerExternalOES in the fragment shader
TEST_P(ImageTestES3, SourceYUVAHBTargetExternalYUVFetchSamplerExternalOES)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() ||
                       !hasExternalESSL3Ext());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(
        2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420, kDefaultAHBYUVUsage, kDefaultAttribs,
        {{kYUVColorRedY, 1}, {kYUVColorRedCb, 1}, {kYUVColorRedCr, 1}}, &source, &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    verifyResultsExternalYUVFetch(target, GLColor::red.data());

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Test texelFetch from a YUV AHB using samplerExternalOES in the vertex shader
TEST_P(ImageTestES3, SourceYUVAHBTargetExternalYUVFetchVSSamplerExternalOES)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() ||
                       !hasExternalESSL3Ext());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(
        2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420, kDefaultAHBYUVUsage, kDefaultAttribs,
        {{kYUVColorRedY, 1}, {kYUVColorRedCb, 1}, {kYUVColorRedCr, 1}}, &source, &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    verifyResultsExternalYUVFetchVS(target, GLColor::red.data());

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Test using glCopySubTextureCHROMIUM with YUV AHB as the source
TEST_P(ImageTestES3, SourceYUVAHBTargetExternalCopySrc)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_CHROMIUM_copy_texture"));

    // 3 planes of data - ensure they are narrow range compatible values
    GLubyte dataY[4]  = {20, 51, 197, 231};
    GLubyte dataCb[1] = {
        128,
    };
    GLubyte dataCr[1] = {
        192,
    };

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(
        2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420, kDefaultAHBYUVUsage, kDefaultAttribs,
        {{dataY, 1}, {dataCb, 1}, {dataCr, 1}}, &source, &image);

    // Create a texture target to bind the egl image
    GLTexture yuv;
    createEGLImageTargetTextureExternal(image, yuv);

    // Create a texture to be the destination of copy
    GLTexture copyDst;
    glBindTexture(GL_TEXTURE_2D, copyDst);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
    glCopySubTextureCHROMIUM(yuv, 0, GL_TEXTURE_2D, copyDst, 0, 0, 0, 0, 0, 2, 2, false, false,
                             false);
    ASSERT_GL_NO_ERROR();

    // Verify the results
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, copyDst, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(107, 0, 5, 255), 2);
    EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(143, 0, 41, 255), 2);
    EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(255, 159, 211, 255), 2);
    EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(255, 198, 250, 255), 2);
    ASSERT_GL_NO_ERROR();

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

TEST_P(ImageTestES3, SourceYUVAHBTargetExternalYUVSampleLinearFiltering)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    ANGLE_SKIP_TEST_IF(!isAndroidHardwareBufferConfigurationSupported(
        2, 4, 1, AHARDWAREBUFFER_FORMAT_YV12, kDefaultAHBYUVUsage));

    // [  Red,   Red]
    // [  Red,   Red]
    // [Black, Black]
    // [Black, Black]

    // clang-format off
    GLubyte dataY[]  = {
        kYUVColorRedY[0], kYUVColorRedY[0],
        kYUVColorRedY[0], kYUVColorRedY[0],
        kYUVColorBlackY[0], kYUVColorBlackY[0],
        kYUVColorBlackY[0], kYUVColorBlackY[0],
    };
    GLubyte dataCb[] = {
        kYUVColorRedCb[0],
        kYUVColorBlackCb[0],
    };
    GLubyte dataCr[] = {
        kYUVColorRedCr[0],
        kYUVColorBlackCr[0],
    };
    // clang-format on

    // Create the Image
    AHardwareBuffer *ahbSource;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(
        2, 4, 1, AHARDWAREBUFFER_FORMAT_YV12, kDefaultAHBYUVUsage, kDefaultAttribs,
        {{dataY, 1}, {dataCb, 1}, {dataCr, 1}}, &ahbSource, &ahbImage);

    ASSERT_GL_NO_ERROR();

    // Create a texture target to bind the egl image
    GLTexture ahbTexture;
    createEGLImageTargetTextureExternal(ahbImage, ahbTexture);

    // Configure linear filtering
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, ahbTexture);
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    // Draw fullscreen sampling from ahbTexture.
    glUseProgram(mTextureExternalProgram);
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, ahbTexture);
    glUniform1i(mTextureExternalUniformLocation, 0);
    drawQuad(mTextureExternalProgram, "position", 0.5f);

    // Framebuffer needs to be bigger than the AHB so there is an area in between that will result
    // in half-red.
    const int windowHeight = getWindowHeight();
    ASSERT_GE(windowHeight, 8);

    EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::black, 1);
    EXPECT_PIXEL_COLOR_NEAR(0, windowHeight - 1, GLColor::red, 1);

    // Approximately half-red:
    EXPECT_PIXEL_COLOR_NEAR(0, windowHeight / 2, GLColor(127, 0, 0, 255), 15.0);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahbSource);
}

// Test to verify that the image view is properly initialized in a program using
// __samplerExternal2DY2YEXT sampler when sampling from the YUV image.
TEST_P(ImageTestES3, SourceYUVAHBTargetExternal2DY2YSample)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() || !hasYUVTargetExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    ANGLE_SKIP_TEST_IF(!isAndroidHardwareBufferConfigurationSupported(
        2, 2, 1, AHARDWAREBUFFER_FORMAT_YCbCr_P210, kDefaultAHBYUVUsage));

    // Create the Image without data so we don't need ANGLE_AHARDWARE_BUFFER_LOCK_PLANES_SUPPORT
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(2, 2, 1, AHARDWAREBUFFER_FORMAT_YCbCr_P210,
                                              kDefaultAHBYUVUsage, kDefaultAttribs, {}, &source,
                                              &image);
    ASSERT_GL_NO_ERROR();

    // Create a texture target to bind the egl image
    GLTexture texture;
    createEGLImageTargetTextureExternal(image, texture);
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
    ASSERT_GL_NO_ERROR();

    // Use the program to sample YUV image directly in a shader
    glUseProgram(mTextureYUVProgram);
    glUniform1i(mTextureYUVUniformLocation, 0);

    // Expect that the image view is created properly without any crashes or assertions
    drawQuad(mTextureYUVProgram, "position", 0.5f);
    ASSERT_GL_NO_ERROR();

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Test rendering to a YUV AHB using EXT_yuv_target
TEST_P(ImageTestES3, RenderToYUVAHB)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() || !hasYUVTargetExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // 3 planes of data, initialize to all zeroes
    GLubyte dataY[4]  = {0, 0, 0, 0};
    GLubyte dataCb[1] = {
        0,
    };
    GLubyte dataCr[1] = {
        0,
    };

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(
        2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420, kDefaultAHBUsage, kDefaultAttribs,
        {{dataY, 1}, {dataCb, 1}, {dataCr, 1}}, &source, &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    // Set up a framebuffer to render into the AHB
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, target,
                           0);
    ASSERT_GL_NO_ERROR();
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    glUseProgram(mRenderYUVProgram2);
    glUniform4f(mRenderYUVUniformLocation, kYUVColorRedY[0] / 255.0f, kYUVColorRedCb[0] / 255.0f,
                kYUVColorRedCr[0] / 255.0f, 1.0f);

    drawQuad(mRenderYUVProgram2, "position", 0.0f);
    ASSERT_GL_NO_ERROR();

    // ReadPixels returns the RGB converted color
    EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, 1.0);

    // Finish before reading back AHB data
    glFinish();

    verifyResultAHB(source, {{kYUVColorRedY, 1}, {kYUVColorRedCb, 1}, {kYUVColorRedCr, 1}});

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Test rendering to a YUV AHB using EXT_yuv_target with a normal depth attachment
TEST_P(ImageTestES3, RenderToYUVAHBWithDepth)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() || !hasYUVTargetExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // 3 planes of data, initialize to all zeroes
    GLubyte dataY[4]  = {0, 0, 0, 0};
    GLubyte dataCb[1] = {
        0,
    };
    GLubyte dataCr[1] = {
        0,
    };

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(
        2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420, kDefaultAHBUsage, kDefaultAttribs,
        {{dataY, 1}, {dataCb, 1}, {dataCr, 1}}, &source, &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    // Create a depth texture
    GLTexture depthTexture;
    glBindTexture(GL_TEXTURE_2D, depthTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 2, 2, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
                 nullptr);
    EXPECT_GL_NO_ERROR();

    // Set up a framebuffer to render into the AHB
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, target,
                           0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
    ASSERT_GL_NO_ERROR();
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    glUseProgram(mRenderYUVProgram);
    glUniform4f(mRenderYUVUniformLocation, kYUVColorRedY[0] / 255.0f, kYUVColorRedCb[0] / 255.0f,
                kYUVColorRedCr[0] / 255.0f, 1.0f);

    drawQuad(mRenderYUVProgram, "position", 0.0f);
    ASSERT_GL_NO_ERROR();

    // ReadPixels returns the RGB converted color
    EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, 1.0);

    // Finish before reading back AHB data
    glFinish();

    verifyResultAHB(source, {{kYUVColorRedY, 1}, {kYUVColorRedCb, 1}, {kYUVColorRedCr, 1}});

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Test clearing to a YUV AHB using EXT_yuv_target
TEST_P(ImageTestES3, ClearYUVAHB)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() || !hasYUVTargetExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    // Create the Image without data so we don't need ANGLE_AHARDWARE_BUFFER_LOCK_PLANES_SUPPORT
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420,
                                              kDefaultAHBUsage, kDefaultAttribs, {}, &source,
                                              &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    // Set up a framebuffer to render into the AHB
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, target,
                           0);
    ASSERT_GL_NO_ERROR();
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Clearing a YUV framebuffer reinterprets the rgba clear color as YUV values and writes them
    // directly to the buffer
    glClearColor(kYUVColorRedY[0] / 255.0f, kYUVColorRedCb[0] / 255.0f, kYUVColorRedCr[0] / 255.0f,
                 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    // ReadPixels returns the RGB converted color
    EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, 1.0);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Test clearing to a YUV AHB using EXT_yuv_target with a normal depth attachment
TEST_P(ImageTestES3, ClearYUVAHBWithDepth)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() || !hasYUVTargetExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    // Create the Image without data so we don't need ANGLE_AHARDWARE_BUFFER_LOCK_PLANES_SUPPORT
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420,
                                              kDefaultAHBUsage, kDefaultAttribs, {}, &source,
                                              &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    // Create a depth texture
    GLTexture depthTexture;
    glBindTexture(GL_TEXTURE_2D, depthTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 2, 2, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
                 nullptr);
    EXPECT_GL_NO_ERROR();

    // Set up a framebuffer to render into the AHB
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, target,
                           0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
    ASSERT_GL_NO_ERROR();
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Clearing a YUV framebuffer reinterprets the rgba clear color as YUV values and writes them
    // directly to the buffer
    glClearColor(kYUVColorRedY[0] / 255.0f, kYUVColorRedCb[0] / 255.0f, kYUVColorRedCr[0] / 255.0f,
                 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    // ReadPixels returns the RGB converted color
    EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, 1.0);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Test partial clearing to a YUV AHB using EXT_yuv_target
TEST_P(ImageTestES3, PartialClearYUVAHB)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() || !hasYUVTargetExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    // Create the Image without data so we don't need ANGLE_AHARDWARE_BUFFER_LOCK_PLANES_SUPPORT
    GLubyte dataY[4]  = {0, 0, 0, 0};
    GLubyte dataCb[1] = {
        0,
    };
    GLubyte dataCr[1] = {
        0,
    };

    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(
        8, 8, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420, kDefaultAHBUsage, kDefaultAttribs,
        {{dataY, 64}, {dataCb, 64}, {dataCr, 64}}, &source, &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    // Set up a framebuffer to render into the AHB
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, target,
                           0);
    ASSERT_GL_NO_ERROR();
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Full clear the background
    glClearColor(kYUVColorBlackY[0] / 255.0f, kYUVColorBlackCb[0] / 255.0f,
                 kYUVColorBlackCr[0] / 255.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::black, 2.0);

    // Partial clear the corner with another color
    glEnable(GL_SCISSOR_TEST);
    glScissor(0, 0, 4, 4);

    glClearColor(kYUVColorRedY[0] / 255.0f, kYUVColorRedCb[0] / 255.0f, kYUVColorRedCr[0] / 255.0f,
                 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    // ReadPixels returns the RGB converted color
    EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, 2.0);
    EXPECT_PIXEL_COLOR_NEAR(4, 4, GLColor::black, 2.0);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Test initial YUV AHB content is preserved during rendering by rendering to only half of the YUV
// AHB.
TEST_P(ImageTestES3, PartialRenderToYUVAHB)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() || !hasYUVTargetExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // 3 planes of data, initialize to a color
    GLubyte dataY[8]  = {kYUVColorBlackY[0], kYUVColorBlackY[0], kYUVColorBlackY[0],
                         kYUVColorBlackY[0], kYUVColorBlackY[0], kYUVColorBlackY[0],
                         kYUVColorBlackY[0], kYUVColorBlackY[0]};
    GLubyte dataCb[2] = {
        kYUVColorBlackCb[0],
        kYUVColorBlackCb[0],
    };
    GLubyte dataCr[2] = {
        kYUVColorBlackCr[0],
        kYUVColorBlackCr[0],
    };

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(
        4, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420, kDefaultAHBUsage, kDefaultAttribs,
        {{dataY, 1}, {dataCb, 1}, {dataCr, 1}}, &source, &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    // Set up a framebuffer to render into the AHB
    glViewport(0, 0, 4, 2);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, target,
                           0);
    ASSERT_GL_NO_ERROR();
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Set up draw to only render to the left half of AHB
    GLint positionLocation              = glGetAttribLocation(mRenderYUVProgram, "position");
    std::array<Vector3, 6> quadVertices = GetQuadVertices();
    for (Vector3 &vertex : quadVertices)
    {
        vertex.x() = (vertex.x() * 0.5f) - 0.5f;
        vertex.z() = 0.0f;
    }
    glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, quadVertices.data());
    glEnableVertexAttribArray(positionLocation);

    glUseProgram(mRenderYUVProgram);
    glUniform4f(mRenderYUVUniformLocation, kYUVColorRedY[0] / 255.0f, kYUVColorRedCb[0] / 255.0f,
                kYUVColorRedCr[0] / 255.0f, 1.0f);

    // Only draw to left half of AHB
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    // Finish before reading back AHB data
    glFinish();

    // Check left half of AHB is draw color
    verifyResultAHB(source, {{kYUVColorRedY, 1}, {kYUVColorRedCb, 1}, {kYUVColorRedCr, 1}},
                    AHBVerifyRegion::LeftHalf);

    // Check right half of AHB is original color
    verifyResultAHB(source, {{kYUVColorBlackY, 1}, {kYUVColorBlackCb, 1}, {kYUVColorBlackCr, 1}},
                    AHBVerifyRegion::RightHalf);

    // Clean up
    glViewport(0, 0, getWindowWidth(), getWindowHeight());
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Test glClear on FBO with AHB attachment is applied to the AHB image before we read back
TEST_P(ImageTestES3, AHBClearAppliedBeforeReadBack)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    const GLubyte kRed[]   = {255, 0, 0, 255};
    const GLubyte kBlack[] = {0, 0, 0, 0};

    // Create one image backed by the AHB.
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {{kBlack, 4}},
                                              &ahb, &ahbImage);
    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    // Create one framebuffer backed by the AHB.
    {
        GLFramebuffer ahbFbo;
        glBindFramebuffer(GL_FRAMEBUFFER, ahbFbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ahbTexture, 0);
        EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        // Clear to red
        glClearColor(1, 0, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT);
        glFinish();
    }

    verifyResultAHB(ahb, {{kRed, 4}});

    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Similar to AHBClearAppliedBeforeReadBack, but clear is applied glClearTexImage().
TEST_P(ImageTestES3, AHBClearAppliedViaClearTexImageBeforeReadBack)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());
    EGLWindow *window = getEGLWindow();

    const GLubyte kRed[]   = {255, 0, 0, 255};
    const GLubyte kBlack[] = {0, 0, 0, 0};

    // Create one image backed by the AHB.
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {{kBlack, 4}},
                                              &ahb, &ahbImage);
    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    // Clear to red
    glClearTexImageEXT(ahbTexture, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
    glFinish();

    verifyResultAHB(ahb, {{kRed, 4}});

    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Similar to AHBClearAppliedBeforeReadBack, but clear is applied twice.
TEST_P(ImageTestES3, AHBTwiceClearAppliedBeforeReadBack)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    const GLubyte kRed[]   = {255, 0, 0, 255};
    const GLubyte kBlack[] = {0, 0, 0, 0};

    // Create one image backed by the AHB.
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {{kBlack, 4}},
                                              &ahb, &ahbImage);
    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    // Create one framebuffer backed by the AHB.
    {
        GLFramebuffer ahbFbo;
        glBindFramebuffer(GL_FRAMEBUFFER, ahbFbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ahbTexture, 0);
        EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        // Clear to green, then to red
        glClearColor(0, 1, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT);
        glClearColor(1, 0, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT);
        glFinish();
    }

    verifyResultAHB(ahb, {{kRed, 4}});

    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Similar to AHBTwiceClearAppliedBeforeReadBack, but clear is applied using glClearTexImage().
TEST_P(ImageTestES3, AHBTwiceClearViaClearTexImageAppliedBeforeReadBack)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());
    EGLWindow *window = getEGLWindow();

    const GLubyte kRed[]   = {255, 0, 0, 255};
    const GLubyte kBlack[] = {0, 0, 0, 0};

    // Create one image backed by the AHB.
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {{kBlack, 4}},
                                              &ahb, &ahbImage);
    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    // Clear to green, then to red
    glClearTexImageEXT(ahbTexture, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
    glClearTexImageEXT(ahbTexture, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
    glFinish();

    verifyResultAHB(ahb, {{kRed, 4}});

    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that glClear on FBO with AHB attachment is applied to the AHB image before detaching the AHB
// image from FBO
TEST_P(ImageTestES3, AHBClearAndDetachBeforeReadback)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    const GLubyte kRed[]   = {255, 0, 0, 255};
    const GLubyte kBlack[] = {0, 0, 0, 0};

    // Create one image backed by the AHB.
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {{kBlack, 4}},
                                              &ahb, &ahbImage);
    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    // Create one framebuffer backed by the AHB.
    {
        GLFramebuffer ahbFbo;
        glBindFramebuffer(GL_FRAMEBUFFER, ahbFbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ahbTexture, 0);
        EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        // Clear to red
        glClearColor(1, 0, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT);

        // Detach the AHB image from the FBO color attachment
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
        glFinish();
    }

    verifyResultAHB(ahb, {{kRed, 4}});

    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that glClear on FBO with AHB color attachment is applied to the AHB image before implicity
// unbinding the AHB image from FBO
TEST_P(ImageTestES3, AHBClearAndAttachAnotherTextureBeforeReadback)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    const GLubyte kRed[]   = {255, 0, 0, 255};
    const GLubyte kBlack[] = {0, 0, 0, 0};

    // Create one image backed by the AHB.
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {{kBlack, 4}},
                                              &ahb, &ahbImage);
    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    // Create one framebuffer backed by the AHB.
    {
        GLFramebuffer ahbFbo;
        glBindFramebuffer(GL_FRAMEBUFFER, ahbFbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ahbTexture, 0);
        EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        // Clear to red
        glClearColor(1, 0, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT);

        // Attach a random texture to the same FBO color attachment slot that AHB image was attached
        // to, this should implicity detach the AHB image from the FBO.
        GLTexture newTexture;
        glBindTexture(GL_TEXTURE_2D, newTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, newTexture, 0);
        glFinish();
    }

    verifyResultAHB(ahb, {{kRed, 4}});

    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test glClear to FBO with AHB color attachment is applied to the AHB image before we switch back
// to the default FBO
TEST_P(ImageTestES3, AHBClearAndSwitchToDefaultFBOBeforeReadBack)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    const GLubyte kRed[]   = {255, 0, 0, 255};
    const GLubyte kBlack[] = {0, 0, 0, 0};

    // Create one image backed by the AHB.
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {{kBlack, 4}},
                                              &ahb, &ahbImage);
    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    // Create one framebuffer backed by the AHB.
    {
        GLFramebuffer ahbFbo;
        glBindFramebuffer(GL_FRAMEBUFFER, ahbFbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ahbTexture, 0);
        EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        // Clear to red
        glClearColor(1, 0, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT);

        // Switch to default FBO
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glFinish();
    }

    verifyResultAHB(ahb, {{kRed, 4}});

    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test glClear on FBO with AHB color attachment is applied to the AHB image with glClientWaitSync
TEST_P(ImageTestES3, AHBClearWithGLClientWaitSyncBeforeReadBack)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    const GLubyte kRed[]   = {255, 0, 0, 255};
    const GLubyte kBlack[] = {0, 0, 0, 0};

    // Create one image backed by the AHB.
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {{kBlack, 4}},
                                              &ahb, &ahbImage);
    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    // Create one framebuffer backed by the AHB.
    {
        GLFramebuffer ahbFbo;
        glBindFramebuffer(GL_FRAMEBUFFER, ahbFbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ahbTexture, 0);
        EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        // Clear to red
        glClearColor(1, 0, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT);

        // Create a GLSync object and immediately wait on it
        GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
        glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED);
    }

    verifyResultAHB(ahb, {{kRed, 4}});

    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test glDraw + glFlush on FBO with AHB attachment are applied to the AHB image before we read back
TEST_P(ImageTestES3, AHBDrawFlushAppliedBeforeReadBack)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport() || !kHasAHBFrontBufferUsageSupport);

    // Create a GLTexture backed by the AHB.
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    const GLubyte kBlack[] = {0, 0, 0, 0};
    const GLubyte kRed[]   = {255, 0, 0, 255};
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage | kAHBUsageFrontBuffer,
                                              kDefaultAttribs, {{kBlack, 4}}, &ahb, &ahbImage);
    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    // Create one framebuffer backed by the AHB-based GLTexture
    GLFramebuffer ahbFbo;
    glBindFramebuffer(GL_FRAMEBUFFER, ahbFbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ahbTexture, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Draw to the FBO and call glFlush()
    ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);

    glUniform4f(colorUniformLocation, kRed[0] / 255.0f, kRed[1] / 255.0f, kRed[2] / 255.0f,
                kRed[3] / 255.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
    glFlush();
    // unlike glFinish(), glFlush() does not wait for commands execution to complete.
    // sleep for 1 second before reading back from AHB.
    angle::Sleep(1000);

    // Verify the result
    verifyResultAHB(ahb, {{kRed, 4}});

    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that glDraw + glFlush on FBO with AHB attachment are applied to the AHB
// image before detaching the AHB image from FBO
TEST_P(ImageTestES3, AHBDrawFlushAndDetachBeforeReadBack)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport() || !kHasAHBFrontBufferUsageSupport);

    // Create a GLTexture backed by the AHB.
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    const GLubyte kBlack[] = {0, 0, 0, 0};
    const GLubyte kRed[]   = {255, 0, 0, 255};
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage | kAHBUsageFrontBuffer,
                                              kDefaultAttribs, {{kBlack, 4}}, &ahb, &ahbImage);
    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    // Create one framebuffer backed by the AHB-based GLTexture
    GLFramebuffer ahbFbo;
    glBindFramebuffer(GL_FRAMEBUFFER, ahbFbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ahbTexture, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Draw to the FBO and call glFlush()
    ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);

    glUniform4f(colorUniformLocation, kRed[0] / 255.0f, kRed[1] / 255.0f, kRed[2] / 255.0f,
                kRed[3] / 255.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);

    glFlush();
    // unlike glFinish(), glFlush() does not wait for commands execution to complete.
    // sleep for 1 second before reading back from AHB.
    angle::Sleep(1000);

    // Detach the AHB image from the FBO color attachment
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);

    // Verify the result
    verifyResultAHB(ahb, {{kRed, 4}});

    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that glDraw + glFlush on FBO with AHB attachment are applied to the AHB
// image before implicitly unbinding the AHB image from FBO
TEST_P(ImageTestES3, AHBDrawFlushAndAttachAnotherTextureBeforeReadBack)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport() || !kHasAHBFrontBufferUsageSupport);

    // Create a GLTexture backed by the AHB.
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    const GLubyte kBlack[] = {0, 0, 0, 0};
    const GLubyte kRed[]   = {255, 0, 0, 255};
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage | kAHBUsageFrontBuffer,
                                              kDefaultAttribs, {{kBlack, 4}}, &ahb, &ahbImage);
    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    // Create one framebuffer backed by the AHB-based GLTexture
    GLFramebuffer ahbFbo;
    glBindFramebuffer(GL_FRAMEBUFFER, ahbFbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ahbTexture, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Draw to the FBO and call glFlush()
    ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);

    glUniform4f(colorUniformLocation, kRed[0] / 255.0f, kRed[1] / 255.0f, kRed[2] / 255.0f,
                kRed[3] / 255.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);

    glFlush();
    // unlike glFinish(), glFlush() does not wait for commands execution to complete.
    // sleep for 1 second before reading back from AHB.
    angle::Sleep(1000);

    // Attach a random texture to the same FBO color attachment slot that AHB image was attached
    // to, this should implicity detach the AHB image from the FBO.
    GLTexture newTexture;
    glBindTexture(GL_TEXTURE_2D, newTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, newTexture, 0);

    // Verify the result
    verifyResultAHB(ahb, {{kRed, 4}});

    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that glDraw + glFlush on FBO with AHB attachment are applied to the AHB
// image before switching to the default FBO
TEST_P(ImageTestES3, AHBDrawFlushAndSwitchToDefaultFBOBeforeReadBack)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport() || !kHasAHBFrontBufferUsageSupport);

    // Create a GLTexture backed by the AHB.
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    const GLubyte kBlack[] = {0, 0, 0, 0};
    const GLubyte kRed[]   = {255, 0, 0, 255};
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage | kAHBUsageFrontBuffer,
                                              kDefaultAttribs, {{kBlack, 4}}, &ahb, &ahbImage);
    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    // Create one framebuffer backed by the AHB-based GLTexture
    GLFramebuffer ahbFbo;
    glBindFramebuffer(GL_FRAMEBUFFER, ahbFbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ahbTexture, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Draw to the FBO and call glFlush()
    ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);

    glUniform4f(colorUniformLocation, kRed[0] / 255.0f, kRed[1] / 255.0f, kRed[2] / 255.0f,
                kRed[3] / 255.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);

    glFlush();
    // unlike glFinish(), glFlush() does not wait for commands execution to complete.
    // sleep for 1 second before reading back from AHB.
    angle::Sleep(1000);

    // Switch to default FBO
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    // Verify the result
    verifyResultAHB(ahb, {{kRed, 4}});

    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that texture swizzle parameters work with EGL image-backed textures
TEST_P(ImageTestES3, AHBTextureSwizzleParameters)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Create the Image
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs,
                                              {{kLinearColor, 4}}, &ahb, &ahbImage);

    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    glBindTexture(GL_TEXTURE_2D, ahbTexture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_GREEN);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_BLUE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);

    GLubyte expectedColor[] = {kLinearColor[1], kLinearColor[2], kLinearColor[0], kLinearColor[3]};
    verifyResults2D(ahbTexture, expectedColor);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that RGBX data are preserved when importing from AHB.  Regression test for a bug in the
// Vulkan backend where the image was cleared due to format emulation.
TEST_P(ImageTestES3, RGBXAHBImportPreservesData)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Create the Image
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs,
                                              {{kLinearColor, 4}}, &ahb, &ahbImage);

    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    verifyResults2D(ahbTexture, kLinearColor);
    verifyResultAHB(ahb, {{kLinearColor, 4}});

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that RGBX data are preserved when importing from AHB created with sRGB color space.
TEST_P(ImageTestES3, RGBXAHBImportPreservesData_Colorspace)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    const GLubyte kRed50SRGB[]   = {188, 0, 0, 255};
    const GLubyte kRed50Linear[] = {128, 0, 0, 255};

    // Create the Image
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM,
                                              kDefaultAHBUsage, kColorspaceAttribs,
                                              {{kRed50SRGB, 4}}, &ahb, &ahbImage);

    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    verifyResults2D(ahbTexture, kRed50Linear);
    verifyResultAHB(ahb, {{kRed50SRGB, 4}});

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Tests that RGBX can be successfully loaded with 3-channel data and read back as 4-channel data.
TEST_P(ImageTestES3, RGBXAHBUploadDownload)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport() || !hasRGBXInternalFormatExt());

    const size_t kWidth  = 32;
    const size_t kHeight = 32;

    const GLubyte kBlack[] = {0, 0, 0, 255};
    const GLubyte kCyan[]  = {0, 255, 255};

    std::vector<GLubyte> pixelsRGBABlack;
    for (size_t h = 0; h < kHeight; h++)
    {
        for (size_t w = 0; w < kWidth; w++)
        {
            pixelsRGBABlack.push_back(kBlack[0]);
            pixelsRGBABlack.push_back(kBlack[1]);
            pixelsRGBABlack.push_back(kBlack[2]);
            pixelsRGBABlack.push_back(kBlack[3]);
        }
    }

    std::vector<GLubyte> pixelsRGBCyan;
    for (size_t h = 0; h < kHeight; h++)
    {
        for (size_t w = 0; w < kWidth; w++)
        {
            pixelsRGBCyan.push_back(kCyan[0]);
            pixelsRGBCyan.push_back(kCyan[1]);
            pixelsRGBCyan.push_back(kCyan[2]);
        }
    }

    // Create the Image
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(
        kWidth, kHeight, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM, kDefaultAHBUsage,
        kDefaultAttribs, {{pixelsRGBABlack.data(), 4}}, &ahb, &ahbImage);

    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    verifyResults2D(ahbTexture, kBlack);
    verifyResultAHB(ahb, {{pixelsRGBABlack.data(), 4}});

    glBindTexture(GL_TEXTURE_2D, ahbTexture);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE,
                    pixelsRGBCyan.data());
    ASSERT_GL_NO_ERROR();

    GLFramebuffer ahbFramebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, ahbFramebuffer);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ahbTexture, 0);
    ASSERT_GL_NO_ERROR();
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    std::vector<GLubyte> readback;
    readback.resize(kWidth * kHeight * 4);
    glReadPixels(0, 0, kWidth, kHeight, GL_RGBX8_ANGLE, GL_UNSIGNED_BYTE, readback.data());

    for (size_t y = 0; y < kHeight; y++)
    {
        const GLubyte *actualRowData = readback.data() + (y * kWidth * 4);
        for (size_t x = 0; x < kWidth; x++)
        {
            const GLubyte *actualPixelData = actualRowData + (x * 4);
            EXPECT_EQ(actualPixelData[0], kCyan[0]) << "at (" << x << ", " << y << ")";
            EXPECT_EQ(actualPixelData[1], kCyan[1]) << "at (" << x << ", " << y << ")";
            EXPECT_EQ(actualPixelData[2], kCyan[2]) << "at (" << x << ", " << y << ")";
        }
    }

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that RGBA data are preserved when importing from AHB and glTexSubImage is able to update
// data.
TEST_P(ImageTestES3, RGBAAHBUploadData)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    const GLubyte kGarbage[]     = {123, 123, 123, 123};
    const GLubyte kRed50Linear[] = {128, 0, 0, 127};

    // Create the Image
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {{kGarbage, 4}},
                                              &ahb, &ahbImage);

    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    glBindTexture(GL_TEXTURE_2D, ahbTexture);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kRed50Linear);
    glFinish();

    verifyResults2D(ahbTexture, kRed50Linear);
    verifyResultAHB(ahb, {{kRed50Linear, 4}});

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that RGBA data are preserved when importing from AHB with sRGB color space and glTexSubImage
// is able to update data.
TEST_P(ImageTestES3, RGBAAHBUploadDataColorspace)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    const GLubyte kGarbage[]     = {123, 123, 123, 123};
    const GLubyte kRed50SRGB[]   = {188, 0, 0, 128};
    const GLubyte kRed50Linear[] = {128, 0, 0, 127};

    // Create the Image
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kColorspaceAttribs, {{kGarbage, 4}},
                                              &ahb, &ahbImage);

    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    glBindTexture(GL_TEXTURE_2D, ahbTexture);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kRed50SRGB);
    glFinish();

    verifyResults2D(ahbTexture, kRed50Linear);
    verifyResultAHB(ahb, {{kRed50SRGB, 4}});

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that RGBX data are preserved when importing from AHB and glTexSubImage is able to update
// data.
TEST_P(ImageTestES3, RGBXAHBUploadData)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    const GLubyte kGarbage[]     = {123, 123, 123, 123};
    const GLubyte kRed50Linear[] = {128, 0, 0, 255};

    // Create the Image
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {{kGarbage, 4}},
                                              &ahb, &ahbImage);

    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    glBindTexture(GL_TEXTURE_2D, ahbTexture);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, kRed50Linear);
    glFinish();

    verifyResults2D(ahbTexture, kRed50Linear);
    verifyResultAHB(ahb, {{kRed50Linear, 4}});

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that RGBX data are preserved when importing from AHB created with sRGB color space and
// glTexSubImage is able to update data.
TEST_P(ImageTestES3, RGBXAHBUploadDataColorspace)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    const GLubyte kGarbage[]     = {123, 123, 123, 123};
    const GLubyte kRed50SRGB[]   = {188, 0, 0, 255};
    const GLubyte kRed50Linear[] = {128, 0, 0, 255};

    // Create the Image
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM,
                                              kDefaultAHBUsage, kColorspaceAttribs,
                                              {{kGarbage, sizeof(kGarbage)}}, &ahb, &ahbImage);

    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    glBindTexture(GL_TEXTURE_2D, ahbTexture);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, kRed50SRGB);
    glFinish();

    verifyResults2D(ahbTexture, kRed50Linear);
    verifyResultAHB(ahb, {{kRed50SRGB, sizeof(kRed50SRGB)}});

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that RGBX data are preserved when importing from AHB and glTexSubImage is able to update
// data using GL_RGBA.
TEST_P(ImageTestES3, RGBXAHBUploadDataRGBA)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    const GLubyte kGarbage[]            = {123, 123, 123, 123};
    const GLubyte kRed50LinearNoAlpha[] = {128, 0, 0, 0};
    const GLubyte kRed50Linear[]        = {128, 0, 0, 255};

    // Create the Image
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {{kGarbage, 4}},
                                              &ahb, &ahbImage);

    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    glBindTexture(GL_TEXTURE_2D, ahbTexture);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kRed50LinearNoAlpha);
    glFinish();

    // Make sure the alpha channel is always 1.
    verifyResults2D(ahbTexture, kRed50Linear);
    verifyResultAHB(ahb, {{kRed50Linear, 4}});

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that RGB data are preserved when importing from AHB created with sRGB color space and
// glTexSubImage is able to update data.
TEST_P(ImageTestES3, RGBAHBUploadDataColorspace)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());
    ANGLE_SKIP_TEST_IF(!isAndroidHardwareBufferConfigurationSupported(
        1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM, kDefaultAHBUsage));

    const GLubyte kGarbage[]     = {123, 123, 123};
    const GLubyte kRed50SRGB[]   = {188, 0, 0};
    const GLubyte kRed50Linear[] = {128, 0, 0, 255};

    // Create the Image
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM,
                                              kDefaultAHBUsage, kColorspaceAttribs,
                                              {{kGarbage, sizeof(kGarbage)}}, &ahb, &ahbImage);

    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    glBindTexture(GL_TEXTURE_2D, ahbTexture);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, kRed50SRGB);
    glFinish();

    verifyResults2D(ahbTexture, kRed50Linear);
    verifyResultAHB(ahb, {{kRed50SRGB, sizeof(kRed50SRGB)}});

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that RGBX data are preserved when importing from AHB.  Tests interaction of emulated channel
// being cleared with no GPU_FRAMEBUFFER usage specified.
TEST_P(ImageTestES3, RGBXAHBImportNoFramebufferUsage)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Create the Image
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM,
                                              kAHBUsageGPUSampledImage, kDefaultAttribs,
                                              {{kLinearColor, 4}}, &ahb, &ahbImage);

    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    verifyResults2D(ahbTexture, kLinearColor);
    verifyResultAHB(ahb, {{kLinearColor, 4}});

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that RGBX data are preserved when importing from AHB.  Tests interaction of emulated channel
// being cleared with multiple layers.
TEST_P(ImageTestES3, RGBXAHBImportMultipleLayers)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Limit the test to single layer for now. writeAHBData is assuming alignment between layers
    // being 4096 which may not true on some GPUs. There is no API to retrieve such alignment from
    // driver. For now just limit to single layer so that we can still test single layer behavior
    // here.
    constexpr size_t kLayerCount = 1;

    ANGLE_SKIP_TEST_IF(!isAndroidHardwareBufferConfigurationSupported(
        1, 1, kLayerCount, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM, kDefaultAHBUsage));

    const GLubyte kInitColor[] = {132, 55, 219, 12, 77, 23, 190, 101, 231, 44, 143, 99};

    // Create the Image
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(
        1, 1, kLayerCount, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM, kDefaultAHBUsage, kDefaultAttribs,
        {{kInitColor, 4}}, &ahb, &ahbImage);

    GLTexture ahbTexture;
    createEGLImageTargetTexture2DArray(ahbImage, ahbTexture);

    // RGBX doesn't have alpha, so readback should return 255.
    const GLubyte kExpectedColor[] = {
        kInitColor[0], kInitColor[1], kInitColor[2], 255,           kInitColor[4],  kInitColor[5],
        kInitColor[6], 255,           kInitColor[8], kInitColor[9], kInitColor[10], 255,
    };
    for (uint32_t layerIndex = 0; layerIndex < kLayerCount; ++layerIndex)
    {
        verifyResults2DArray(ahbTexture, kExpectedColor + 4 * layerIndex, layerIndex);
    }
    verifyResultAHB(ahb, {{kExpectedColor, 4}});

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that RGBX data are preserved when importing from AHB.  Tests interaction of emulated channel
// being cleared with glReadPixels.
TEST_P(ImageTestES3, RGBXAHBImportThenReadPixels)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Create the Image
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs,
                                              {{kLinearColor, 4}}, &ahb, &ahbImage);

    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ahbTexture, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // RGBX doesn't have alpha, so readback should return 255.  kLinearColor[3] is already 255.
    EXPECT_PIXEL_NEAR(0, 0, kLinearColor[0], kLinearColor[1], kLinearColor[2], kLinearColor[3], 1);

    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    verifyResults2D(ahbTexture, kLinearColor);
    verifyResultAHB(ahb, {{kLinearColor, 4}});

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that RGBX data are preserved when importing from AHB.  Tests interaction of emulated channel
// being cleared with a following clear.
TEST_P(ImageTestES3, RGBXAHBImportThenClear)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Create the Image
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs,
                                              {{kLinearColor, 4}}, &ahb, &ahbImage);

    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ahbTexture, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Clear
    const GLubyte kClearColor[] = {63, 127, 191, 55};
    glClearColor(kClearColor[0] / 255.0f, kClearColor[1] / 255.0f, kClearColor[2] / 255.0f,
                 kClearColor[3] / 255.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    // RGBX doesn't have alpha, so readback should return 255.
    const GLubyte kExpectedColor[] = {kClearColor[0], kClearColor[1], kClearColor[2], 255};
    verifyResults2D(ahbTexture, kExpectedColor);
    verifyResultAHB(ahb, {{kExpectedColor, 4}});

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that RGBX data are preserved when importing from AHB.  Tests interaction of emulated channel
// being cleared with a following clear and a draw call.
TEST_P(ImageTestES3, RGBXAHBImportThenClearThenDraw)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Create the Image
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs,
                                              {{kLinearColor, 4}}, &ahb, &ahbImage);

    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ahbTexture, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Clear
    const GLubyte kClearColor[] = {63, 127, 191, 55};
    glClearColor(kClearColor[0] / 255.0f, kClearColor[1] / 255.0f, kClearColor[2] / 255.0f,
                 kClearColor[3] / 255.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // Draw with blend
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);

    ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);

    glUniform4f(colorUniformLocation, 0.25f, 0.25f, 0.25f, 0.25f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glDisable(GL_BLEND);

    // RGBX doesn't have alpha, so readback should return 255.
    const GLubyte kExpectedColor[] = {static_cast<GLubyte>(kClearColor[0] + 64),
                                      static_cast<GLubyte>(kClearColor[1] + 64),
                                      static_cast<GLubyte>(kClearColor[2] + 64), 255};
    verifyResults2D(ahbTexture, kExpectedColor);
    verifyResultAHB(ahb, {{kExpectedColor, 4}});

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test that RGBX data are preserved when importing from AHB.  Tests interaction of emulated channel
// being cleared with a following data upload.
TEST_P(ImageTestES3, RGBXAHBImportThenUpload)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    const GLubyte kInitColor[] = {132, 55, 219, 12, 132, 55, 219, 12};

    // Create the Image
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(2, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {{kInitColor, 4}},
                                              &ahb, &ahbImage);

    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    // Upload data
    const GLubyte kUploadColor[] = {63, 127, 191, 55};
    glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, kUploadColor);
    ASSERT_GL_NO_ERROR();

    // RGBX doesn't have alpha, so readback should return 255.
    const GLubyte kExpectedColorRight[] = {kUploadColor[0], kUploadColor[1], kUploadColor[2], 255};
    const GLubyte kExpectedColorLeft[]  = {kInitColor[0], kInitColor[1], kInitColor[2], 255};
    verifyResults2DLeftAndRight(ahbTexture, kExpectedColorLeft, kExpectedColorRight);
    verifyResultAHB(ahb, {{kExpectedColorLeft, 4}}, AHBVerifyRegion::LeftHalf);
    verifyResultAHB(ahb, {{kExpectedColorRight, 4}}, AHBVerifyRegion::RightHalf);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Tests interaction of emulated channel being cleared with a following data upload and immediately
// ends to check that the image updates are processed and flushed without errors. It is similar to
// RGBXAHBImportThenUpload, but there is no pixel reading or destroying the image to avoid extra
// staged update flushes.
TEST_P(ImageTestES3, IncompleteRGBXAHBImportThenUploadThenEnd)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    const GLubyte kInitColor[] = {132, 55, 219, 12, 132, 55, 219, 12};

    // Create the Image
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(2, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {{kInitColor, 4}},
                                              &ahb, &ahbImage);

    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    // Upload data
    const GLubyte kUploadColor[] = {63, 127, 191, 55};
    glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, kUploadColor);
    ASSERT_GL_NO_ERROR();

    // Clean up
    destroyAndroidHardwareBuffer(ahb);
    // This test relies on internal assertions to catch the issue regarding unflushed updates after
    // clearing emulated channels.
}

// Test that RGBX data are preserved when importing from AHB.  Tests interaction of emulated channel
// being cleared with occlusion queries.
TEST_P(ImageTestES3, RGBXAHBImportOcclusionQueryNotCounted)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    GLQueryEXT query;
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);

    // Create the Image
    AHardwareBuffer *ahb;
    EGLImageKHR ahbImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs,
                                              {{kLinearColor, 4}}, &ahb, &ahbImage);

    GLTexture ahbTexture;
    createEGLImageTargetTexture2D(ahbImage, ahbTexture);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ahbTexture, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Perform a masked clear.  Both the emulated clear and the masked clear should be performed,
    // neither of which should contribute to the occlusion query.
    const GLubyte kClearColor[] = {63, 127, 191, 55};
    glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE);
    glClearColor(kClearColor[0] / 255.0f, kClearColor[1] / 255.0f, kClearColor[2] / 255.0f,
                 kClearColor[3] / 255.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    ASSERT_GL_NO_ERROR();

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

    // RGBX doesn't have alpha, so readback should return 255.
    const GLubyte kExpectedColor[] = {kClearColor[0], kLinearColor[1], kClearColor[2], 255};
    verifyResults2D(ahbTexture, kExpectedColor);
    verifyResultAHB(ahb, {{kExpectedColor, 4}});

    GLuint result = GL_TRUE;
    glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);
    EXPECT_GL_NO_ERROR();

    EXPECT_GL_FALSE(result);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), ahbImage);
    destroyAndroidHardwareBuffer(ahb);
}

// Test repeatedly importing and releasing AHBs into textures to replicate behavior where
// SurfaceFlinger optimistically imports AHBs but never actually ends up using them. Regression
// test to check that AHB releases are not left pending and kept alive to avoid running out of
// memory.
TEST_P(ImageTestES3, AHBImportReleaseStress)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Counters only available on Vulkan.
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    const GLubyte kBlack[] = {0, 0, 0, 0};

    glFinish();

    GLPerfMonitor monitor;
    glBeginPerfMonitorAMD(monitor);

    const uint64_t initialPendingSubmissionGarbageObjects =
        getPerfCounters().pendingSubmissionGarbageObjects;

    for (int i = 0; i < 20; i++)
    {
        AHardwareBuffer *ahb;
        EGLImageKHR ahbImage;
        createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                                  kDefaultAHBUsage, kDefaultAttribs, {{kBlack, 4}},
                                                  &ahb, &ahbImage);

        {
            GLTexture ahbTexture;
            glBindTexture(GL_TEXTURE_2D, ahbTexture);
            glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, ahbImage);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            ASSERT_GL_NO_ERROR();

            // Intentionally not doing anything which may explicitly flush operations on the AHB.
        }

        eglDestroyImageKHR(getEGLWindow()->getDisplay(), ahbImage);
        destroyAndroidHardwareBuffer(ahb);
    }

    glEndPerfMonitorAMD(monitor);

    EXPECT_LE(getPerfCounters().pendingSubmissionGarbageObjects,
              initialPendingSubmissionGarbageObjects + 10);
}

// Test validation of using EXT_yuv_target
TEST_P(ImageTestES3, YUVValidation)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() || !hasYUVTargetExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    // Create the Image without data so we don't need ANGLE_AHARDWARE_BUFFER_LOCK_PLANES_SUPPORT
    AHardwareBuffer *yuvSource;
    EGLImageKHR yuvImage;
    createEGLImageAndroidHardwareBufferSource(2, 2, 1, AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420,
                                              kDefaultAHBUsage, kDefaultAttribs, {}, &yuvSource,
                                              &yuvImage);

    GLTexture yuvTexture;
    createEGLImageTargetTextureExternal(yuvImage, yuvTexture);

    GLFramebuffer yuvFbo;
    glBindFramebuffer(GL_FRAMEBUFFER, yuvFbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES,
                           yuvTexture, 0);
    ASSERT_GL_NO_ERROR();
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Create an rgba image
    AHardwareBuffer *rgbaSource;
    EGLImageKHR rgbaImage;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {}, &rgbaSource,
                                              &rgbaImage);

    GLTexture rgbaExternalTexture;
    createEGLImageTargetTextureExternal(rgbaImage, rgbaExternalTexture);

    GLFramebuffer rgbaExternalFbo;
    glBindFramebuffer(GL_FRAMEBUFFER, rgbaExternalFbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES,
                           rgbaExternalTexture, 0);
    ASSERT_GL_NO_ERROR();
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Create a 2d rgb texture/framebuffer
    GLTexture rgb2DTexture;
    glBindTexture(GL_TEXTURE_2D, rgb2DTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);

    GLFramebuffer rgb2DFbo;
    glBindFramebuffer(GL_FRAMEBUFFER, rgb2DFbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rgb2DTexture, 0);
    ASSERT_GL_NO_ERROR();
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // It's an error to sample from a non-yuv external texture with a yuv sampler
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glUseProgram(mTextureYUVProgram);
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, rgbaExternalTexture);
    glUniform1i(mTextureYUVUniformLocation, 0);

    drawQuad(mTextureYUVProgram, "position", 0.5f);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    // It's an error to render into a YUV framebuffer without a YUV writing program
    glBindFramebuffer(GL_FRAMEBUFFER, yuvFbo);
    glUseProgram(mTextureExternalESSL3Program);
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, rgbaExternalTexture);
    glUniform1i(mTextureExternalESSL3UniformLocation, 0);

    drawQuad(mTextureExternalESSL3Program, "position", 0.5f);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    // It's an error to render to a RGBA framebuffer with a YUV writing program
    glBindFramebuffer(GL_FRAMEBUFFER, rgb2DFbo);
    glUseProgram(mRenderYUVProgram);

    drawQuad(mRenderYUVProgram, "position", 0.5f);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    // It's an error to disable r, g, b, a writes when rendering to a yuv framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, yuvFbo);
    glUseProgram(mRenderYUVProgram);

    glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
    drawQuad(mRenderYUVProgram, "position", 0.5f);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE);
    drawQuad(mRenderYUVProgram, "position", 0.5f);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
    drawQuad(mRenderYUVProgram, "position", 0.5f);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
    drawQuad(mRenderYUVProgram, "position", 0.5f);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

    // It's an error to enable blending when rendering to a yuv framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, yuvFbo);
    glUseProgram(mRenderYUVProgram);

    glEnable(GL_BLEND);
    drawQuad(mRenderYUVProgram, "position", 0.5f);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
    glDisable(GL_BLEND);

    // It's an error to blit to/from a yuv framebuffer
    glBindFramebuffer(GL_READ_FRAMEBUFFER, yuvFbo);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, rgb2DFbo);
    glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    glBindFramebuffer(GL_READ_FRAMEBUFFER, rgb2DFbo);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, yuvFbo);
    glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    // It's an error to glCopyTexImage/glCopyTexSubImage from a YUV framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, yuvFbo);
    glBindTexture(GL_TEXTURE_2D, rgb2DTexture);
    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 1, 1, 0);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), yuvImage);
    destroyAndroidHardwareBuffer(yuvSource);

    eglDestroyImageKHR(window->getDisplay(), rgbaImage);
    destroyAndroidHardwareBuffer(rgbaSource);
}

// Testing source AHB EGL image with colorspace, target external ESSL3 texture
TEST_P(ImageTestES3, SourceAHBTargetExternalESSL3_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_sRGB"));
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    SourceAHBTargetExternalESSL3_helper(kColorspaceAttribs);
}

void ImageTest::SourceAHBTargetExternalESSL3_helper(const EGLint *attribs)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() ||
                       !hasExternalESSL3Ext());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, attribs, {{kSrgbColor, 4}}, &source,
                                              &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    // Use texture target bound to egl image as source and render to framebuffer
    // Verify that the target texture has the expected color
    verifyResultsExternalESSL3(target, getExpected2DColorForAttribList(attribs));

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Testing source multi-layered AHB EGL image, target 2D array texture
TEST_P(ImageTestES3, SourceAHBArrayTarget2DArray)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() ||
                       !hasEglImageArrayExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    constexpr size_t kDepth = 2;

    ANGLE_SKIP_TEST_IF(!isAndroidHardwareBufferConfigurationSupported(
        1, 1, kDepth, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, kDefaultAHBUsage));

    // Create the Image without data so we don't need ANGLE_AHARDWARE_BUFFER_LOCK_PLANES_SUPPORT
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(1, 1, kDepth, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {}, &source,
                                              &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTexture2DArray(image, target);

    // Upload texture data
    glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 1, 1, kDepth, GL_RGBA, GL_UNSIGNED_BYTE,
                    kLinearColor3D);

    // Use texture target bound to egl image as source and render to framebuffer
    for (size_t layer = 0; layer < kDepth; layer++)
    {
        // Expect that the target texture has the same color as the source texture
        verifyResults2DArray(target, &kLinearColor3D[layer * 4], layer);
    }

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Testing source cubemap AHB EGL image, target cubemap texture
TEST_P(ImageTestES3, SourceAHBCubeTargetCube)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasEglImageStorageExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    ANGLE_SKIP_TEST_IF(!isAndroidHardwareBufferConfigurationSupported(
        1, 1, kCubeFaceCount, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
        kDefaultAHBUsage | kAHBUsageGPUCubeMap));

    // Create the Image without data so we don't need ANGLE_AHARDWARE_BUFFER_LOCK_PLANES_SUPPORT
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(
        1, 1, kCubeFaceCount, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
        kDefaultAHBUsage | kAHBUsageGPUCubeMap, kDefaultAttribs, {}, &source, &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureStorage(image, GL_TEXTURE_CUBE_MAP, target, nullptr);

    // Upload texture data
    for (size_t faceIdx = 0; faceIdx < kCubeFaceCount; faceIdx++)
    {
        glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIdx, 0, 0, 0, 1, 1, GL_RGBA,
                        GL_UNSIGNED_BYTE, &kLinearColorCube[faceIdx * 4]);
        ASSERT_GL_NO_ERROR();
    }

    // Use texture target bound to egl image as source and render to framebuffer
    for (size_t faceIdx = 0; faceIdx < kCubeFaceCount; faceIdx++)
    {
        // Expect that the target texture has the same color as the source texture
        verifyResultsCube(target, &kLinearColorCube[faceIdx * 4], faceIdx);
    }

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Testing source cubemap array AHB EGL image, target cubemap array texture
TEST_P(ImageTestES31, SourceAHBCubeArrayTargetCubeArray)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!(getClientMajorVersion() >= 3 && getClientMinorVersion() >= 1));
    ANGLE_SKIP_TEST_IF(!hasEglImageStorageExt() ||
                       !IsGLExtensionEnabled("GL_EXT_texture_cube_map_array"));
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    constexpr size_t kDepth = kCubeFaceCount * 2;
    ANGLE_SKIP_TEST_IF(!isAndroidHardwareBufferConfigurationSupported(
        1, 1, kDepth, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
        kDefaultAHBUsage | kAHBUsageGPUCubeMap));

    // Create the Image without data so we don't need ANGLE_AHARDWARE_BUFFER_LOCK_PLANES_SUPPORT
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(1, 1, kDepth, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage | kAHBUsageGPUCubeMap,
                                              kDefaultAttribs, {}, &source, &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureStorage(image, GL_TEXTURE_CUBE_MAP_ARRAY, target, nullptr);

    // Upload texture data
    for (size_t faceIdx = 0; faceIdx < kCubeFaceCount; faceIdx++)
    {
        glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, faceIdx, 1, 1, 1, GL_RGBA,
                        GL_UNSIGNED_BYTE, &kLinearColorCube[faceIdx * 4]);
        glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 11 - faceIdx, 1, 1, 1, GL_RGBA,
                        GL_UNSIGNED_BYTE, &kLinearColorCube[faceIdx * 4]);
        ASSERT_GL_NO_ERROR();
    }

    // Use texture target bound to egl image as source and render to framebuffer
    for (size_t faceIdx = 0; faceIdx < kCubeFaceCount; faceIdx++)
    {
        // Expect that the target texture has the same color as the source texture
        verifyResultsCubeArray(target, &kLinearColorCube[faceIdx * 4], faceIdx, 0);
        verifyResultsCubeArray(target, &kLinearColorCube[(5 - faceIdx) * 4], faceIdx, 1);
    }

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Testing source 2D AHB with mipmap EGL image, target 2D texture with mipmap
TEST_P(ImageTestES3, SourceAHBMipTarget2DMip)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasEglImageStorageExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    ANGLE_SKIP_TEST_IF(!isAndroidHardwareBufferConfigurationSupported(
        2, 2, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
        kDefaultAHBUsage | kAHBUsageGPUMipMapComplete));

    // Create the Image without data so we don't need ANGLE_AHARDWARE_BUFFER_LOCK_PLANES_SUPPORT
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(2, 2, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage | kAHBUsageGPUMipMapComplete,
                                              kDefaultAttribs, {}, &source, &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureStorage(image, GL_TEXTURE_2D, target, nullptr);

    // Upload texture data
    // Set Mip level 0 to one color
    const std::vector<GLColor> kRedData(4, GLColor::red);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, kRedData.data());

    // Set Mip level 1 to a different color
    const std::vector<GLColor> kGreenData(1, GLColor::green);
    glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kGreenData.data());

    // Use texture target bound to egl image as source and render to framebuffer
    // Expect that the target texture has the same color as the corresponding mip level in the
    // source texture
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
    verifyResults2D(target, GLColor::red.data());

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
    verifyResults2D(target, GLColor::green.data());

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Test glGenerateMipmap and GL_EXT_EGL_image_storage interaction
TEST_P(ImageTestES3, SourceAHBMipTarget2DMipGenerateMipmap)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasEglImageStorageExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    ANGLE_SKIP_TEST_IF(!isAndroidHardwareBufferConfigurationSupported(
        2, 2, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
        kDefaultAHBUsage | kAHBUsageGPUMipMapComplete));

    // Create the Image without data so we don't need ANGLE_AHARDWARE_BUFFER_LOCK_PLANES_SUPPORT
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(2, 2, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage | kAHBUsageGPUMipMapComplete,
                                              kDefaultAttribs, {}, &source, &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTextureStorage(image, GL_TEXTURE_2D, target, nullptr);

    // Upload texture data
    // Set Mip level 0 to one color
    const std::vector<GLColor> kRedData(4, GLColor::red);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, kRedData.data());

    // Set Mip level 1 to a different color
    const std::vector<GLColor> kGreenData(1, GLColor::green);
    glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kGreenData.data());

    // Generate mipmap level 1
    glGenerateMipmap(GL_TEXTURE_2D);

    // Use mipmap level 1 of texture target bound to egl image as source and render to framebuffer
    // Expect that the target texture has the same color as the mip level 0 in the source texture
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
    verifyResults2D(target, GLColor::red.data());

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Create a depth format AHB backed EGL image and verify that the image's aspect is honored
TEST_P(ImageTest, SourceAHBTarget2DDepth)
{
    // TODO - Support for depth formats in AHB is missing (http://anglebug.com/42263405)
    ANGLE_SKIP_TEST_IF(true);

    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    GLint level             = 0;
    GLsizei width           = 1;
    GLsizei height          = 1;
    GLsizei depth           = 1;
    GLint depthStencilValue = 0;

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(
        width, height, depth, AHARDWAREBUFFER_FORMAT_D24_UNORM, kDefaultAHBUsage, kDefaultAttribs,
        {{reinterpret_cast<GLubyte *>(&depthStencilValue), 3}}, &source, &image);

    // Create a texture target to bind the egl image
    GLTexture depthTextureTarget;
    createEGLImageTargetTexture2D(image, depthTextureTarget);

    // Create a color texture and fill it with red
    GLTexture colorTexture;
    glBindTexture(GL_TEXTURE_2D, colorTexture);
    glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::red.data());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glBindTexture(GL_TEXTURE_2D, 0);
    EXPECT_GL_NO_ERROR();

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    EXPECT_GL_NO_ERROR();

    // Attach the color and depth texture to the FBO
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
    EXPECT_GL_NO_ERROR();
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTextureTarget,
                           0);
    EXPECT_GL_NO_ERROR();

    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));

    // Clear the color texture to red
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);

    // Enable Depth test but disable depth writes. The depth function is set to ">".
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_FALSE);
    glDepthFunc(GL_GREATER);

    // Fill any fragment of the color attachment with blue if it passes the depth test.
    ANGLE_GL_PROGRAM(colorFillProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
    drawQuad(colorFillProgram, essl1_shaders::PositionAttrib(), 1.0f, 1.0f);

    // Since 1.0f > 0.0f, all fragments of the color attachment should be blue.
    EXPECT_PIXEL_EQ(0, 0, 0, 0, 255, 255);

    // Clean up
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

TEST_P(ImageTest, Source2DTargetRenderbuffer)
{
    Source2DTargetRenderbuffer_helper(kDefaultAttribs);
}

TEST_P(ImageTest, Source2DTargetRenderbuffer_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    Source2DTargetRenderbuffer_helper(kColorspaceAttribs);
}

void ImageTest::Source2DTargetRenderbuffer_helper(const EGLint *attribs)
{

    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    // Create sampling texture
    GLTexture sampleTexture;
    glBindTexture(GL_TEXTURE_2D, sampleTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, kLinearColor);
    // Disable mipmapping
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    ASSERT_GL_NO_ERROR();

    // Create the attachment texture and image
    GLTexture attachmentTexture;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, attribs, nullptr,
                                  attachmentTexture, &image);

    // Create the renderbuffer
    GLRenderbuffer renderbuffer;
    createEGLImageTargetRenderbuffer(image, renderbuffer);

    // Verify that the render buffer has the expected color
    verifyResultsRenderbufferWithClearAndDraw(
        sampleTexture, renderbuffer, kLinearColor,
        getExpected2DColorForAttribList(attribs, EglImageUsage::Rendering));

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Testing source native client buffer EGL image, target external texture
// where source native client buffer is created using EGL_ANDROID_create_native_client_buffer API
TEST_P(ImageTest, SourceNativeClientBufferTargetExternal)
{
    SourceNativeClientBufferTargetExternal_helper(kDefaultAttribs);
}

// Testing source native client buffer EGL image with colorspace, target external texture
// where source native client buffer is created using EGL_ANDROID_create_native_client_buffer API
TEST_P(ImageTest, SourceNativeClientBufferTargetExternal_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    SourceNativeClientBufferTargetExternal_helper(kColorspaceAttribs);
}

void ImageTest::SourceNativeClientBufferTargetExternal_helper(const EGLint *attribs)
{

    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Create an Image backed by a native client buffer allocated using
    // EGL_ANDROID_create_native_client_buffer API
    EGLImageKHR image;
    createEGLImageANWBClientBufferSource(1, 1, 1, kNativeClientBufferAttribs_RGBA8_Texture, attribs,
                                         {{kSrgbColor, 4}}, &image);

    // Create the target
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    // Verify that the target texture has the expected color
    verifyResultsExternal(target, getExpected2DColorForAttribList(attribs));

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Testing source native client buffer EGL image, target Renderbuffer
// where source native client buffer is created using EGL_ANDROID_create_native_client_buffer API
TEST_P(ImageTest, SourceNativeClientBufferTargetRenderbuffer)
{
    SourceNativeClientBufferTargetRenderbuffer_helper(kDefaultAttribs);
}

// Testing source native client buffer EGL image with colorspace, target Renderbuffer
// where source native client buffer is created using EGL_ANDROID_create_native_client_buffer API
TEST_P(ImageTest, SourceNativeClientBufferTargetRenderbuffer_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    SourceNativeClientBufferTargetRenderbuffer_helper(kColorspaceAttribs);
}

void ImageTest::SourceNativeClientBufferTargetRenderbuffer_helper(const EGLint *attribs)
{

    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    // Create an Image backed by a native client buffer allocated using
    // EGL_ANDROID_create_native_client_buffer API
    EGLImageKHR image = EGL_NO_IMAGE_KHR;
    createEGLImageANWBClientBufferSource(1, 1, 1, kNativeClientBufferAttribs_RGBA8_Renderbuffer,
                                         attribs, {{kSrgbColor, 4}}, &image);
    // We are locking AHB to initialize AHB with data. The lock is allowed to fail, and may fail if
    // driver decided to allocate with framebuffer compression enabled.
    ANGLE_SKIP_TEST_IF(image == EGL_NO_IMAGE_KHR);

    // Create the target
    GLRenderbuffer target;
    createEGLImageTargetRenderbuffer(image, target);

    // Create a framebuffer with renderbuffer attachment and clear it
    GLFramebuffer framebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, target);
    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();

    // Verify that the render buffer has the expected color
    verifyResultsRenderbuffer(target,
                              getExpected2DColorForAttribList(attribs, EglImageUsage::Rendering));

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

TEST_P(ImageTest, Source2DTargetExternal)
{
    Source2DTargetExternal_helper(kDefaultAttribs);
}

TEST_P(ImageTest, Source2DTargetExternal_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_sRGB"));
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    Source2DTargetExternal_helper(kColorspaceAttribs);
}

void ImageTest::Source2DTargetExternal_helper(const EGLint *attribs)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() || !hasExternalExt());

    // Ozone only supports external target for images created with EGL_EXT_image_dma_buf_import
    ANGLE_SKIP_TEST_IF(IsOzone());

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, attribs, kSrgbColor, source,
                                  &image);

    // Create the target
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    // Verify that the target texture has the expected color
    verifyResultsExternal(target, getExpected2DColorForAttribList(attribs));

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

TEST_P(ImageTestES3, Source2DTargetExternalESSL3)
{
    Source2DTargetExternalESSL3_helper(kDefaultAttribs);
}

TEST_P(ImageTestES3, Source2DTargetExternalESSL3_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_sRGB"));
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    Source2DTargetExternalESSL3_helper(kColorspaceAttribs);
}

void ImageTest::Source2DTargetExternalESSL3_helper(const EGLint *attribs)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() ||
                       !hasExternalESSL3Ext());

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, attribs, kSrgbColor, source,
                                  &image);

    // Create the target
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    // Verify that the target texture has the expected color
    verifyResultsExternalESSL3(target, getExpected2DColorForAttribList(attribs));

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

TEST_P(ImageTest, SourceCubeTarget2D)
{
    SourceCubeTarget2D_helper(kDefaultAttribs);
}

TEST_P(ImageTest, SourceCubeTarget2D_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_sRGB"));
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    SourceCubeTarget2D_helper(kColorspaceAttribs);
}

void ImageTest::SourceCubeTarget2D_helper(const EGLint *attribs)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !hasCubemapExt());

    for (EGLenum faceIdx = 0; faceIdx < 6; faceIdx++)
    {
        // Create the Image
        GLTexture source;
        EGLImageKHR image;
        createEGLImageCubemapTextureSource(
            1, 1, GL_RGBA, GL_UNSIGNED_BYTE, attribs, reinterpret_cast<uint8_t *>(kSrgbColorCube),
            sizeof(GLubyte) * 4, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR + faceIdx, source, &image);

        // Create the target
        GLTexture target;
        createEGLImageTargetTexture2D(image, target);

        // Verify that the target texture has the expected color
        verifyResults2D(target, &getExpectedCubeColorForAttribList(attribs)[faceIdx * 4]);

        // Clean up
        eglDestroyImageKHR(window->getDisplay(), image);
    }
}

TEST_P(ImageTest, SourceCubeTargetRenderbuffer)
{
    SourceCubeTargetRenderbuffer_helper(kDefaultAttribs);
}

TEST_P(ImageTest, SourceCubeTargetRenderbuffer_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    SourceCubeTargetRenderbuffer_helper(kColorspaceAttribs);
}

void ImageTest::SourceCubeTargetRenderbuffer_helper(const EGLint *attribs)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !hasCubemapExt());

    // http://anglebug.com/42261821
    ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsFuchsia());

    for (EGLenum faceIdx = 0; faceIdx < 6; faceIdx++)
    {
        // Create the Image
        GLTexture source;
        EGLImageKHR image;
        createEGLImageCubemapTextureSource(
            1, 1, GL_RGBA, GL_UNSIGNED_BYTE, attribs, reinterpret_cast<uint8_t *>(kSrgbColorCube),
            sizeof(GLubyte) * 4, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR + faceIdx, source, &image);

        // Create the target
        GLRenderbuffer target;
        createEGLImageTargetRenderbuffer(image, target);

        // Create a framebuffer with renderbuffer attachment and clear it
        GLFramebuffer framebuffer;
        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, target);
        glClearColor(
            kLinearColorCube[faceIdx * 4 + 0] / 255.0f, kLinearColorCube[faceIdx * 4 + 1] / 255.0f,
            kLinearColorCube[faceIdx * 4 + 2] / 255.0f, kLinearColorCube[faceIdx * 4 + 3] / 255.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        ASSERT_GL_NO_ERROR();

        // Verify that the render buffer has the expected color
        verifyResultsRenderbuffer(target, &getExpectedCubeColorForAttribList(
                                              attribs, EglImageUsage::Rendering)[faceIdx * 4]);

        // Clean up
        eglDestroyImageKHR(window->getDisplay(), image);
    }
}

// Test cubemap -> external texture EGL images.
TEST_P(ImageTest, SourceCubeTargetExternal)
{
    SourceCubeTargetExternal_helper(kDefaultAttribs);
}

TEST_P(ImageTest, SourceCubeTargetExternal_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_sRGB"));
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    SourceCubeTargetExternal_helper(kColorspaceAttribs);
}

void ImageTest::SourceCubeTargetExternal_helper(const EGLint *attribs)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !hasCubemapExt() || !hasExternalExt());

    // Ozone only supports external target for images created with EGL_EXT_image_dma_buf_import
    ANGLE_SKIP_TEST_IF(IsOzone());

    for (EGLenum faceIdx = 0; faceIdx < 6; faceIdx++)
    {
        // Create the Image
        GLTexture source;
        EGLImageKHR image;
        // Upload sRGB color so that it is converted to linear when sampling.
        createEGLImageCubemapTextureSource(
            1, 1, GL_RGBA, GL_UNSIGNED_BYTE, attribs, reinterpret_cast<uint8_t *>(kSrgbColorCube),
            sizeof(GLubyte) * 4, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR + faceIdx, source, &image);

        // Create the target
        GLTexture target;
        createEGLImageTargetTextureExternal(image, target);

        // Verify that the target texture has the expected color
        verifyResultsExternal(target, &getExpectedCubeColorForAttribList(attribs)[faceIdx * 4]);

        // Clean up
        eglDestroyImageKHR(window->getDisplay(), image);
    }
}

// Test cubemap -> external texture EGL images using ESSL3 shaders.
TEST_P(ImageTestES3, SourceCubeTargetExternalESSL3)
{
    SourceCubeTargetExternalESSL3_helper(kDefaultAttribs);
}

TEST_P(ImageTestES3, SourceCubeTargetExternalESSL3_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_sRGB"));
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    SourceCubeTargetExternalESSL3_helper(kColorspaceAttribs);
}

void ImageTest::SourceCubeTargetExternalESSL3_helper(const EGLint *attribs)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasExternalESSL3Ext() || !hasBaseExt() || !hasCubemapExt());

    for (EGLenum faceIdx = 0; faceIdx < 6; faceIdx++)
    {
        // Create the Image
        GLTexture source;
        EGLImageKHR image;
        // Upload sRGB color so that it is converted to linear when sampling.
        createEGLImageCubemapTextureSource(
            1, 1, GL_RGBA, GL_UNSIGNED_BYTE, attribs, reinterpret_cast<uint8_t *>(kSrgbColorCube),
            sizeof(GLubyte) * 4, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR + faceIdx, source, &image);

        // Create the target
        GLTexture target;
        createEGLImageTargetTextureExternal(image, target);

        // Verify that the target texture has the expected color
        verifyResultsExternalESSL3(target,
                                   &getExpectedCubeColorForAttribList(attribs)[faceIdx * 4]);

        // Clean up
        eglDestroyImageKHR(window->getDisplay(), image);
    }
}

TEST_P(ImageTest, Source3DTargetTexture)
{
    Source3DTargetTexture_helper(default3DAttribs);
}

TEST_P(ImageTest, Source3DTargetTexture_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_sRGB"));
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    Source3DTargetTexture_helper(colorspace3DAttribs);
}

void ImageTest::Source3DTargetTexture_helper(EGLint *attribs)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has3DTextureExt());

    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_OES_texture_3D"));

    constexpr size_t depth = 2;

    for (size_t layer = 0; layer < depth; layer++)
    {
        // Create the Image
        GLTexture source;
        EGLImageKHR image;
        // Upload sRGB color so that it is converted to linear when sampling.
        attribs[kTextureZOffsetAttributeIndex] = static_cast<EGLint>(layer);
        createEGLImage3DTextureSource(1, 1, depth, GL_RGBA, GL_UNSIGNED_BYTE, attribs, kSrgbColor3D,
                                      source, &image);

        // Create the target
        GLTexture target;
        createEGLImageTargetTexture2D(image, target);

        // Verify that the target texture has the expected color
        verifyResults2D(target, &getExpected3DColorForAttribList(attribs)[layer * 4]);

        // Clean up
        eglDestroyImageKHR(window->getDisplay(), image);
    }
}

TEST_P(ImageTest, Source3DTargetRenderbuffer)
{
    Source3DTargetRenderbuffer_helper(default3DAttribs);
}

TEST_P(ImageTest, Source3DTargetRenderbuffer_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    Source3DTargetRenderbuffer_helper(colorspace3DAttribs);
}

void ImageTest::Source3DTargetRenderbuffer_helper(EGLint *attribs)
{
    // Qualcom drivers appear to always bind the 0 layer of the source 3D texture when the
    // target is a renderbuffer. They work correctly when the target is a 2D texture.
    // http://anglebug.com/42261453
    ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());

    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has3DTextureExt());

    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_OES_texture_3D"));

    constexpr size_t depth = 2;

    for (size_t layer = 0; layer < depth; layer++)
    {
        // Create the Image
        GLTexture source;
        EGLImageKHR image;

        attribs[kTextureZOffsetAttributeIndex] = static_cast<EGLint>(layer);
        createEGLImage3DTextureSource(1, 1, depth, GL_RGBA, GL_UNSIGNED_BYTE, attribs, kSrgbColor3D,
                                      source, &image);

        // Create the target
        GLRenderbuffer target;
        createEGLImageTargetRenderbuffer(image, target);

        // Create a framebuffer with renderbuffer attachment and clear it
        GLFramebuffer framebuffer;
        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, target);
        glClearColor(kLinearColor3D[layer * 4 + 0] / 255.0f, kLinearColor3D[layer * 4 + 1] / 255.0f,
                     kLinearColor3D[layer * 4 + 2] / 255.0f,
                     kLinearColor3D[layer * 4 + 3] / 255.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        ASSERT_GL_NO_ERROR();

        // Verify that the render buffer has the expected color
        verifyResultsRenderbuffer(
            target, &getExpected3DColorForAttribList(attribs, EglImageUsage::Rendering)[layer * 4]);

        // Clean up
        eglDestroyImageKHR(window->getDisplay(), image);
    }
}

// Test 3D -> external texture EGL images.
TEST_P(ImageTest, Source3DTargetExternal)
{
    Source3DTargetExternal_helper(default3DAttribs);
}

TEST_P(ImageTest, Source3DTargetExternal_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_sRGB"));
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    Source3DTargetExternal_helper(colorspace3DAttribs);
}

void ImageTest::Source3DTargetExternal_helper(EGLint *attribs)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasExternalExt() || !hasBaseExt() || !has3DTextureExt());

    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_OES_texture_3D"));

    // Ozone only supports external target for images created with EGL_EXT_image_dma_buf_import
    ANGLE_SKIP_TEST_IF(IsOzone());

    constexpr size_t depth = 2;

    for (size_t layer = 0; layer < depth; layer++)
    {
        // Create the Image
        GLTexture source;
        EGLImageKHR image;
        // Upload sRGB color so that it is converted to linear when sampling.
        attribs[kTextureZOffsetAttributeIndex] = static_cast<EGLint>(layer);
        createEGLImage3DTextureSource(1, 1, depth, GL_RGBA, GL_UNSIGNED_BYTE, attribs, kSrgbColor3D,
                                      source, &image);

        // Create the target
        GLTexture target;
        createEGLImageTargetTextureExternal(image, target);

        // Verify that the target texture has the expected color
        verifyResultsExternal(target, &getExpected3DColorForAttribList(attribs)[layer * 4]);

        // Clean up
        eglDestroyImageKHR(window->getDisplay(), image);
    }
}

// Test 3D -> external texture EGL images using ESSL3 shaders.
TEST_P(ImageTestES3, Source3DTargetExternalESSL3)
{
    Source3DTargetExternalESSL3_helper(default3DAttribs);
}

TEST_P(ImageTestES3, Source3DTargetExternalESSL3_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_sRGB"));
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    Source3DTargetExternalESSL3_helper(colorspace3DAttribs);
}

void ImageTest::Source3DTargetExternalESSL3_helper(EGLint *attribs)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasExternalESSL3Ext() || !hasBaseExt() ||
                       !has3DTextureExt());

    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_OES_texture_3D"));

    constexpr size_t depth = 2;

    for (size_t layer = 0; layer < depth; layer++)
    {
        // Create the Image
        GLTexture source;
        EGLImageKHR image;
        // Upload sRGB color so that it is converted to linear when sampling.
        attribs[kTextureZOffsetAttributeIndex] = static_cast<EGLint>(layer);
        createEGLImage3DTextureSource(1, 1, depth, GL_RGBA, GL_UNSIGNED_BYTE, attribs, kSrgbColor3D,
                                      source, &image);

        // Create the target
        GLTexture target;
        createEGLImageTargetTextureExternal(image, target);

        // Verify that the target texture has the expected color
        verifyResultsExternalESSL3(target, &getExpected3DColorForAttribList(attribs)[layer * 4]);

        // Clean up
        eglDestroyImageKHR(window->getDisplay(), image);
    }
}

TEST_P(ImageTest, SourceRenderbufferTargetTexture)
{
    SourceRenderbufferTargetTexture_helper(kDefaultAttribs);
}

TEST_P(ImageTest, SourceRenderbufferTargetTexture_Colorspace)
{
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    SourceRenderbufferTargetTexture_helper(kColorspaceAttribs);
}

void ImageTest::SourceRenderbufferTargetTexture_helper(const EGLint *attribs)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !hasRenderbufferExt());

    // Create the Image
    GLRenderbuffer source;
    EGLImageKHR image;
    createEGLImageRenderbufferSource(1, 1, GL_RGBA8_OES, attribs, source, &image);

    // Create a framebuffer with renderbuffer attachment and clear it
    GLFramebuffer framebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, source);
    glClearColor(kSrgbColor[0] / 255.0f, kSrgbColor[1] / 255.0f, kSrgbColor[2] / 255.0f,
                 kSrgbColor[3] / 255.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    ASSERT_GL_NO_ERROR();

    // Create the target
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Verify that the target texture has the expected color
    verifyResults2D(target, getExpected2DColorForAttribList(attribs));

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Test renderbuffer -> external texture EGL images.
TEST_P(ImageTest, SourceRenderbufferTargetTextureExternal)
{
    SourceRenderbufferTargetTextureExternal_helper(kDefaultAttribs);
}

TEST_P(ImageTest, SourceRenderbufferTargetTextureExternal_Colorspace)
{
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    SourceRenderbufferTargetTextureExternal_helper(kColorspaceAttribs);
}

void ImageTest::SourceRenderbufferTargetTextureExternal_helper(const EGLint *attribs)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasExternalExt() || !hasBaseExt() || !hasRenderbufferExt());

    // Ozone only supports external target for images created with EGL_EXT_image_dma_buf_import
    ANGLE_SKIP_TEST_IF(IsOzone());

    // Create the Image
    GLRenderbuffer source;
    EGLImageKHR image;
    createEGLImageRenderbufferSource(1, 1, GL_RGBA8_OES, attribs, source, &image);

    // Create a framebuffer with renderbuffer attachment and clear it
    GLFramebuffer framebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, source);
    glClearColor(kSrgbColor[0] / 255.0f, kSrgbColor[1] / 255.0f, kSrgbColor[2] / 255.0f,
                 kSrgbColor[3] / 255.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    ASSERT_GL_NO_ERROR();

    // Create the target
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    // Verify that the target texture has the expected color
    verifyResultsExternal(target, getExpected2DColorForAttribList(attribs));

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Test renderbuffer -> external texture EGL images using ESSL3 shaders.
TEST_P(ImageTestES3, SourceRenderbufferTargetTextureExternalESSL3)
{
    SourceRenderbufferTargetTextureExternalESSL3_helper(kDefaultAttribs);
}

TEST_P(ImageTestES3, SourceRenderbufferTargetTextureExternalESSL3_Colorspace)
{
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    SourceRenderbufferTargetTextureExternalESSL3_helper(kColorspaceAttribs);
}

void ImageTest::SourceRenderbufferTargetTextureExternalESSL3_helper(const EGLint *attribs)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasExternalESSL3Ext() || !hasBaseExt() ||
                       !hasRenderbufferExt());

    // Create the Image
    GLRenderbuffer source;
    EGLImageKHR image;
    createEGLImageRenderbufferSource(1, 1, GL_RGBA8_OES, attribs, source, &image);

    // Create a framebuffer with renderbuffer attachment and clear it
    GLFramebuffer framebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, source);
    glClearColor(kSrgbColor[0] / 255.0f, kSrgbColor[1] / 255.0f, kSrgbColor[2] / 255.0f,
                 kSrgbColor[3] / 255.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    // Create the target
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    // Verify that the target texture has the expected color
    verifyResultsExternalESSL3(target, getExpected2DColorForAttribList(attribs));

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

TEST_P(ImageTest, SourceRenderbufferTargetRenderbuffer)
{
    SourceRenderbufferTargetRenderbuffer_helper(kDefaultAttribs);
}

TEST_P(ImageTest, SourceRenderbufferTargetRenderbuffer_Colorspace)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_sRGB"));
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    SourceRenderbufferTargetRenderbuffer_helper(kColorspaceAttribs);
}

void ImageTest::SourceRenderbufferTargetRenderbuffer_helper(const EGLint *attribs)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !hasRenderbufferExt());

    // Create the Image
    GLRenderbuffer source;
    EGLImageKHR image;
    createEGLImageRenderbufferSource(1, 1, GL_RGBA8_OES, attribs, source, &image);

    // Create the target
    GLRenderbuffer target;
    createEGLImageTargetRenderbuffer(image, target);

    // Create a framebuffer with renderbuffer attachment and clear it
    GLFramebuffer framebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, target);
    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();

    // Verify that the render buffer has the expected color
    verifyResultsRenderbuffer(target,
                              getExpected2DColorForAttribList(attribs, EglImageUsage::Rendering));

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

void ImageTest::FixedRatedCompressionBasicHelper(const GLint *attribs)
{
    constexpr size_t width  = 16;
    constexpr size_t height = 16;
    GLTexture textureSource;
    EGLImageKHR image;
    EGLWindow *window = getEGLWindow();
    createEGLImage2DTextureStorage(width, height, GL_RGBA8, attribs, textureSource, &image);

    GLTexture textureAttachment;
    createEGLImageTargetTextureStorage(image, GL_TEXTURE_2D, textureAttachment, attribs);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    ASSERT_GL_NO_ERROR();
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureAttachment,
                           0);
    ASSERT_GL_NO_ERROR();
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0);
    EXPECT_PIXEL_RECT_EQ(0, 0, width, height, GLColor::red);
    ASSERT_GL_NO_ERROR();
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Test basic usage of extension GL_EXT_EGL_image_storage_compression
TEST_P(ImageTest, FixedRatedCompressionBasic)
{
    ANGLE_SKIP_TEST_IF(!hasEglImageStorageExt() || !hasEglImageStorageCompressionExt());
    ANGLE_SKIP_TEST_IF(!hasTextureStorageCompressionExt());
    constexpr GLint kAttribList[3][3] = {
        {GL_NONE, GL_NONE, GL_NONE},
        {GL_SURFACE_COMPRESSION_EXT, GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT, GL_NONE},
        {GL_SURFACE_COMPRESSION_EXT, GL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT, GL_NONE},
    };
    for (const GLint *attribs : kAttribList)
    {
        FixedRatedCompressionBasicHelper(attribs);
    }
}

void ImageTest::FixedRatedCompressionImageAttribCheck(EGLImageKHR image,
                                                      const GLint *attribs,
                                                      const GLint expectResult)
{
    GLTexture textureAttachment;
    // Create a target texture from the image
    glBindTexture(GL_TEXTURE_2D, textureAttachment);
    glEGLImageTargetTexStorageEXT(GL_TEXTURE_2D, image, attribs);
    ASSERT_GL_ERROR(expectResult);
}

// Test whether the result is expected when the attributes mismatched with source
TEST_P(ImageTest, FixedRatedCompressionMixedAttrib)
{
    ANGLE_SKIP_TEST_IF(!hasEglImageStorageExt() || !hasEglImageStorageCompressionExt());
    ANGLE_SKIP_TEST_IF(!hasTextureStorageCompressionExt());
    constexpr size_t width                 = 16;
    constexpr size_t height                = 16;
    EGLWindow *window                      = getEGLWindow();
    constexpr GLint textureAttribList[][3] = {
        {GL_NONE, GL_NONE, GL_NONE},
        {GL_SURFACE_COMPRESSION_EXT, GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT, GL_NONE},
        {GL_SURFACE_COMPRESSION_EXT, GL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT, GL_NONE},
    };
    constexpr GLint imageAttribList[][3] = {
        {GL_NONE, GL_NONE, GL_NONE},
        {GL_SURFACE_COMPRESSION_EXT, GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT, GL_NONE},
    };

    constexpr GLint invalidImageAttribList[][3] = {
        {GL_SURFACE_COMPRESSION_EXT, GL_SURFACE_COMPRESSION_EXT, GL_NONE},
        {GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT, GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT,
         GL_NONE},
    };

    for (const GLint *textureAttribs : textureAttribList)
    {
        GLTexture textureSource;
        EGLImageKHR image;
        bool isFixRatedCompressed;
        createEGLImage2DTextureStorage(width, height, GL_RGBA8, textureAttribs, textureSource,
                                       &image);
        /* Query compression rate */
        GLint compressRate = GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT;
        glGetTexParameteriv(GL_TEXTURE_2D, GL_SURFACE_COMPRESSION_EXT, &compressRate);
        ASSERT_GL_NO_ERROR();
        isFixRatedCompressed = (compressRate == GL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT ||
                                (compressRate >= GL_SURFACE_COMPRESSION_FIXED_RATE_1BPC_EXT &&
                                 compressRate <= GL_SURFACE_COMPRESSION_FIXED_RATE_12BPC_EXT));

        for (const GLint *attribs : imageAttribList)
        {
            if (isFixRatedCompressed && attribs[0] == GL_SURFACE_COMPRESSION_EXT &&
                attribs[1] == GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT)
            {
                FixedRatedCompressionImageAttribCheck(image, attribs, GL_INVALID_OPERATION);
            }
            else
            {
                FixedRatedCompressionImageAttribCheck(image, attribs, GL_NO_ERROR);
            }
        }

        for (const GLint *attribs : invalidImageAttribList)
        {
            FixedRatedCompressionImageAttribCheck(image, attribs, GL_INVALID_VALUE);
        }

        eglDestroyImageKHR(window->getDisplay(), image);
    }
}

// Delete the source texture and EGL image.  The image targets should still have the same data
// because
// they hold refs to the image.
TEST_P(ImageTest, Deletion)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    GLubyte originalData[4] = {255, 0, 255, 255};
    GLubyte updateData[4]   = {0, 255, 0, 255};

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs, originalData,
                                  source, &image);

    // Create multiple targets
    GLTexture targetTexture;
    createEGLImageTargetTexture2D(image, targetTexture);

    GLRenderbuffer targetRenderbuffer;
    createEGLImageTargetRenderbuffer(image, targetRenderbuffer);

    // Delete the source texture
    source.reset();

    // Expect that both the targets have the original data
    verifyResults2D(targetTexture, originalData);
    verifyResultsRenderbuffer(targetRenderbuffer, originalData);

    // Update the data of the target
    glBindTexture(GL_TEXTURE_2D, targetTexture);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, updateData);

    // Expect that both targets have the updated data
    verifyResults2D(targetTexture, updateData);
    verifyResultsRenderbuffer(targetRenderbuffer, updateData);

    // Delete the EGL image
    eglDestroyImageKHR(window->getDisplay(), image);
    image = EGL_NO_IMAGE_KHR;

    // Update the data of the target back to the original data
    glBindTexture(GL_TEXTURE_2D, targetTexture);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData);

    // Expect that both targets have the original data again
    verifyResults2D(targetTexture, originalData);
    verifyResultsRenderbuffer(targetRenderbuffer, originalData);
}

TEST_P(ImageTest, MipLevels)
{
    // Driver returns OOM in read pixels, some internal error.
    ANGLE_SKIP_TEST_IF(IsOzone() && IsOpenGLES());
    // Also fails on NVIDIA Shield TV bot.
    // http://anglebug.com/42262494
    ANGLE_SKIP_TEST_IF(IsNVIDIAShield() && IsOpenGLES());
    // On Vulkan, the clear operation in the loop is optimized with a render pass loadOp=Clear.  On
    // Linux/Intel, that operation is mistakenly clearing the rest of the mips to 0.
    // http://anglebug.com/42261962
    ANGLE_SKIP_TEST_IF(IsVulkan() && IsLinux() && IsIntel());

    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    const size_t mipLevels   = 3;
    const size_t textureSize = 4;
    std::vector<GLColor> mip0Data(textureSize * textureSize, GLColor::red);
    std::vector<GLColor> mip1Data(mip0Data.size() << 1, GLColor::green);
    std::vector<GLColor> mip2Data(mip0Data.size() << 2, GLColor::blue);
    GLubyte *data[mipLevels] = {
        reinterpret_cast<GLubyte *>(&mip0Data[0]),
        reinterpret_cast<GLubyte *>(&mip1Data[0]),
        reinterpret_cast<GLubyte *>(&mip2Data[0]),
    };

    GLTexture source;
    glBindTexture(GL_TEXTURE_2D, source);

    for (size_t level = 0; level < mipLevels; level++)
    {
        glTexImage2D(GL_TEXTURE_2D, static_cast<GLint>(level), GL_RGBA, textureSize >> level,
                     textureSize >> level, 0, GL_RGBA, GL_UNSIGNED_BYTE, data[level]);
    }

    ASSERT_GL_NO_ERROR();

    for (size_t level = 0; level < mipLevels; level++)
    {
        // Create the Image
        EGLint attribs[] = {
            EGL_GL_TEXTURE_LEVEL_KHR,
            static_cast<EGLint>(level),
            EGL_NONE,
        };
        EGLImageKHR image =
            eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
                              reinterpretHelper<EGLClientBuffer>(source), attribs);
        ASSERT_EGL_SUCCESS();

        // Create a texture and renderbuffer target
        GLTexture textureTarget;
        createEGLImageTargetTexture2D(image, textureTarget);

        // Disable mipmapping
        glBindTexture(GL_TEXTURE_2D, textureTarget);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        GLRenderbuffer renderbufferTarget;
        createEGLImageTargetRenderbuffer(image, renderbufferTarget);

        // Expect that the targets have the same color as the source texture
        verifyResults2D(textureTarget, data[level]);
        verifyResultsRenderbuffer(renderbufferTarget, data[level]);

        // Update the data by uploading data to the texture
        std::vector<GLuint> textureUpdateData(textureSize * textureSize, level);
        glBindTexture(GL_TEXTURE_2D, textureTarget);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, textureSize >> level, textureSize >> level, GL_RGBA,
                        GL_UNSIGNED_BYTE, textureUpdateData.data());
        ASSERT_GL_NO_ERROR();

        // Expect that both the texture and renderbuffer see the updated texture data
        verifyResults2D(textureTarget, reinterpret_cast<GLubyte *>(textureUpdateData.data()));
        verifyResultsRenderbuffer(renderbufferTarget,
                                  reinterpret_cast<GLubyte *>(textureUpdateData.data()));

        // Update the renderbuffer by clearing it
        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
                                  renderbufferTarget);

        GLubyte clearValue = static_cast<GLubyte>(level);
        GLubyte renderbufferClearData[4]{clearValue, clearValue, clearValue, clearValue};
        glClearColor(renderbufferClearData[0] / 255.0f, renderbufferClearData[1] / 255.0f,
                     renderbufferClearData[2] / 255.0f, renderbufferClearData[3] / 255.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        ASSERT_GL_NO_ERROR();

        // Expect that both the texture and renderbuffer see the cleared renderbuffer data
        verifyResults2D(textureTarget, renderbufferClearData);
        verifyResultsRenderbuffer(renderbufferTarget, renderbufferClearData);

        // Clean up
        eglDestroyImageKHR(window->getDisplay(), image);
    }
}

// Respecify the source texture, orphaning it.  The target texture should not have updated data.
TEST_P(ImageTest, Respecification)
{
    // Respecification of textures that does not change the size of the level attached to the EGL
    // image does not cause orphaning on Qualcomm devices. http://anglebug.com/42261452
    ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
    ANGLE_SKIP_TEST_IF(IsOzone() && IsOpenGLES());

    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    GLubyte originalData[4] = {255, 0, 255, 255};
    GLubyte updateData[4]   = {0, 255, 0, 255};

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs, originalData,
                                  source, &image);

    // Create the target
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Respecify source
    glBindTexture(GL_TEXTURE_2D, source);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, updateData);

    // Expect that the target texture has the original data
    verifyResults2D(target, originalData);

    // Expect that the source texture has the updated data
    verifyResults2D(source, updateData);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Respecify the source texture with a different size, orphaning it.  The target texture should not
// have updated data.
TEST_P(ImageTest, RespecificationDifferentSize)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    GLubyte originalData[4] = {255, 0, 255, 255};
    GLubyte updateData[16]  = {0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255};

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs, originalData,
                                  source, &image);

    // Create the target
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Respecify source
    glBindTexture(GL_TEXTURE_2D, source);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, updateData);

    // Expect that the target texture has the original data
    verifyResults2D(target, originalData);

    // Expect that the source texture has the updated data
    verifyResults2D(source, updateData);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// First render to a target texture, then respecify the source texture, orphaning it.
// The target texture's FBO should be notified of the target texture's orphaning.
TEST_P(ImageTest, RespecificationWithFBO)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());

    GLubyte originalData[4] = {255, 0, 255, 255};
    GLubyte updateData[4]   = {0, 255, 0, 255};

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs, originalData,
                                  source, &image);

    // Create the target
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Render to the target texture
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target, 0);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);

    // Respecify source with same parameters. This should not change the texture storage in D3D11.
    glBindTexture(GL_TEXTURE_2D, source);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, updateData);

    // Expect that the source texture has the updated data
    verifyResults2D(source, updateData);

    // Render to the target texture again and verify it gets the rendered pixels.
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Test that respecifying a level of the target texture orphans it and keeps a copy of the EGLimage
// data
TEST_P(ImageTest, RespecificationOfOtherLevel)
{
    // Respecification of textures that does not change the size of the level attached to the EGL
    // image does not cause orphaning on Qualcomm devices. http://anglebug.com/42261452
    ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());

    // It is undefined what happens to the mip 0 of the dest texture after it is orphaned. Some
    // backends explicitly copy the data but Vulkan does not.
    ANGLE_SKIP_TEST_IF(IsVulkan());

    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    GLubyte originalData[2 * 2 * 4] = {
        255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255,
    };

    GLubyte updateData[2 * 2 * 4] = {
        0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
    };

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(2, 2, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs, originalData,
                                  source, &image);

    // Create the target
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Expect that the target and source textures have the original data
    verifyResults2D(source, originalData);
    verifyResults2D(target, originalData);

    // Add a new mipLevel to the target, orphaning it
    glBindTexture(GL_TEXTURE_2D, target);
    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, originalData);
    EXPECT_GL_NO_ERROR();

    // Expect that the target and source textures still have the original data
    verifyResults2D(source, originalData);
    verifyResults2D(target, originalData);

    // Update the source's data
    glBindTexture(GL_TEXTURE_2D, source);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, updateData);

    // Expect that the target still has the original data and source has the updated data
    verifyResults2D(source, updateData);
    verifyResults2D(target, originalData);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Update the data of the source and target textures.  All image siblings should have the new data.
TEST_P(ImageTest, UpdatedData)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    GLubyte originalData[4] = {255, 0, 255, 255};
    GLubyte updateData[4]   = {0, 255, 0, 255};

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs, originalData,
                                  source, &image);

    // Create multiple targets
    GLTexture targetTexture;
    createEGLImageTargetTexture2D(image, targetTexture);

    GLRenderbuffer targetRenderbuffer;
    createEGLImageTargetRenderbuffer(image, targetRenderbuffer);

    // Expect that both the source and targets have the original data
    verifyResults2D(source, originalData);
    verifyResults2D(targetTexture, originalData);
    verifyResultsRenderbuffer(targetRenderbuffer, originalData);

    // Update the data of the source
    glBindTexture(GL_TEXTURE_2D, source);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, updateData);

    // Expect that both the source and targets have the updated data
    verifyResults2D(source, updateData);
    verifyResults2D(targetTexture, updateData);
    verifyResultsRenderbuffer(targetRenderbuffer, updateData);

    // Update the data of the target back to the original data
    glBindTexture(GL_TEXTURE_2D, targetTexture);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData);

    // Expect that both the source and targets have the original data again
    verifyResults2D(source, originalData);
    verifyResults2D(targetTexture, originalData);
    verifyResultsRenderbuffer(targetRenderbuffer, originalData);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Check that the external texture is successfully updated when only glTexSubImage2D is called.
TEST_P(ImageTest, AHBUpdatedExternalTexture)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    GLubyte originalData[4]      = {255, 0, 255, 255};
    GLubyte updateData[4]        = {0, 255, 0, 255};
    const uint32_t bytesPerPixel = 4;

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs,
                                              {{originalData, bytesPerPixel}}, &source, &image);

    // Create target
    GLTexture targetTexture;
    createEGLImageTargetTexture2D(image, targetTexture);

    // Expect that both the target have the original data
    verifyResults2D(targetTexture, originalData);

    // Update the data of the source
    glBindTexture(GL_TEXTURE_2D, targetTexture);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, updateData);

    // Set sync object and flush the GL commands
    EGLSyncKHR fence = eglCreateSyncKHR(window->getDisplay(), EGL_SYNC_FENCE_KHR, NULL);
    ASSERT_NE(fence, EGL_NO_SYNC_KHR);
    glFlush();

    // Delete the target texture
    targetTexture.reset();

    // Wait that the flush command is finished
    EGLint result = eglClientWaitSyncKHR(window->getDisplay(), fence, 0, 1000000000);
    ASSERT_EQ(result, EGL_CONDITION_SATISFIED_KHR);
    ASSERT_EGL_TRUE(eglDestroySyncKHR(window->getDisplay(), fence));

    // Delete the EGL image
    eglDestroyImageKHR(window->getDisplay(), image);

    // Access the android hardware buffer directly to check the data is updated
    verifyResultAHB(source, {{updateData, bytesPerPixel}});

    // Create the EGL image again
    image =
        eglCreateImageKHR(window->getDisplay(), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
                          angle::android::AHardwareBufferToClientBuffer(source), kDefaultAttribs);
    ASSERT_EGL_SUCCESS();

    // Create the target texture again
    GLTexture targetTexture2;
    createEGLImageTargetTexture2D(image, targetTexture2);

    // Expect that the target have the update data
    verifyResults2D(targetTexture2, updateData);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Check that the texture is successfully updated using PBO.
TEST_P(ImageTest, AHBUpdatedUnpackBuffer)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    GLubyte originalData[4 * 4] = {
        0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
        0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
    };

    static const unsigned char pbo[] = {
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
        0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF,
        0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
    };
    GLubyte resultData[4 * 4] = {
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
        0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF,
    };
    const uint32_t bytesPerPixel = 4;

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(2, 2, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs,
                                              {{originalData, bytesPerPixel}}, &source, &image);

    // Create target
    GLTexture targetTexture;
    createEGLImageTargetTexture2D(image, targetTexture);

    // Expect that both the target have the original data
    verifyResults2D(targetTexture, originalData);

    GLBuffer buf;
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
    glPixelStorei(GL_UNPACK_ROW_LENGTH, 1);
    glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(pbo), NULL, GL_DYNAMIC_DRAW);
    glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, sizeof(pbo), pbo);
    EXPECT_GL_NO_ERROR();

    // Update the data of the source
    glBindTexture(GL_TEXTURE_2D, targetTexture);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 2, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 0, 1, 2, GL_RGBA, GL_UNSIGNED_BYTE, 0);

    // Set sync object and flush the GL commands
    EGLSyncKHR fence = eglCreateSyncKHR(window->getDisplay(), EGL_SYNC_FENCE_KHR, NULL);
    ASSERT_NE(fence, EGL_NO_SYNC_KHR);
    glFlush();

    // Wait that the flush command is finished
    EGLint result = eglClientWaitSyncKHR(window->getDisplay(), fence, 0, 1000000000);
    ASSERT_EQ(result, EGL_CONDITION_SATISFIED_KHR);
    ASSERT_EGL_TRUE(eglDestroySyncKHR(window->getDisplay(), fence));

    // Delete the EGL image
    eglDestroyImageKHR(window->getDisplay(), image);

    // Access the android hardware buffer directly to check the data is updated
    verifyResultAHB(source, {{resultData, bytesPerPixel}});

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    destroyAndroidHardwareBuffer(source);
}

// Check that the texture successfully updates when an image is deleted
TEST_P(ImageTest, DeletedImageWithSameSizeAndFormat)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    GLubyte originalData[4] = {255, 0, 255, 255};
    GLubyte updateData[4]   = {0, 255, 0, 255};

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs, originalData,
                                  source, &image);

    // Create texture & bind to Image
    GLTexture texture;
    createEGLImageTargetTexture2D(image, texture);

    // Delete Image
    eglDestroyImageKHR(window->getDisplay(), image);

    ASSERT_EGL_SUCCESS();

    // Redefine Texture
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, updateData);

    ASSERT_GL_NO_ERROR();
}

// Check that create a source cube texture and then redefine the same target texture with each face
// of source cube texture renders correctly
TEST_P(ImageTest, SourceCubeAndSameTargetTextureWithEachCubeFace)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    // Create a source cube map texture
    GLTexture sourceTexture;
    glBindTexture(GL_TEXTURE_CUBE_MAP, sourceTexture);
    uint8_t *data     = reinterpret_cast<uint8_t *>(kLinearColorCube);
    size_t dataStride = sizeof(GLubyte) * 4;
    for (GLenum faceIdx = 0; faceIdx < 6; faceIdx++)
    {
        glTexImage2D(faceIdx + GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, data + (faceIdx * dataStride));
    }
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    ASSERT_GL_NO_ERROR();

    EGLImageKHR images[6];
    GLTexture targetTexture;
    glBindTexture(GL_TEXTURE_2D, targetTexture);

    for (GLenum faceIdx = 0; faceIdx < 6; faceIdx++)
    {
        // Create the Image with EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR
        images[faceIdx] =
            eglCreateImageKHR(window->getDisplay(), window->getContext(),
                              EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR + faceIdx,
                              reinterpretHelper<EGLClientBuffer>(sourceTexture), kDefaultAttribs);

        // Create a target texture from the image
        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, images[faceIdx]);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        ASSERT_GL_NO_ERROR();
        // Expect that the target texture has the same color as the source texture
        verifyResults2D(targetTexture, &kLinearColorCube[faceIdx * 4]);
    }

    // Clean up
    for (GLenum faceIdx = 0; faceIdx < 6; faceIdx++)
    {
        eglDestroyImageKHR(window->getDisplay(), images[faceIdx]);
    }
}

// Case for testing External Texture support in MEC.
// To run this test with the right capture setting, make sure to set these environment variables:
//
// For Linux:
//      export ANGLE_CAPTURE_FRAME_START=2
//      export ANGLE_CAPTURE_FRAME_END=2
//      export ANGLE_CAPTURE_LABEL=external_textures
//      export ANGLE_CAPTURE_OUT_DIR=[PATH_TO_ANGLE]/src/tests/restricted_traces/external_textures/
//
// For Android:
//      adb shell setprop debug.angle.capture.frame_start 2
//      adb shell setprop debug.angle.capture.frame_end 2
//      adb shell setprop debug.angle.capture.label external_textures
//      adb shell setprop debug.angle.capture.out_dir /data/data/externaltextures/angle_capture/
TEST_P(ImageTest, AppTraceExternalTextureDefaultAttribs)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() ||
                       !hasExternalESSL3Ext());

    constexpr EGLint attribs[] = {
        EGL_IMAGE_PRESERVED,
        EGL_TRUE,
        EGL_NONE,
    };

    externalTextureTracerTestHelper(attribs);
}

// Same as AppTraceExternalTextureUseCase, except we will pass additional attrib_list values in
// EGLAttrib* for eglCreateImageKHR calls
TEST_P(ImageTest, AppTraceExternalTextureOtherAttribs)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() ||
                       !hasExternalESSL3Ext());

    constexpr EGLint attribs[] = {
        EGL_IMAGE_PRESERVED, EGL_TRUE, EGL_GL_TEXTURE_LEVEL, 0, EGL_NONE,
    };

    externalTextureTracerTestHelper(attribs);
}

// Same as AppTraceExternalTextureUseCase, except we will pass nullptr as EGLAttrib* for
// eglCreateImageKHR calls
TEST_P(ImageTest, AppTraceExternalTextureNullAttribs)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() ||
                       !hasExternalESSL3Ext());

    externalTextureTracerTestHelper(nullptr);
}

// Alternate case for testing External Texture (created with AHB) support in MEC.
// Make sure to use the following environment variables for the right capture setting on Android:
//
// adb shell setprop debug.angle.capture.frame_start 2
// adb shell setprop debug.angle.capture.frame_end 2
// adb shell setprop debug.angle.capture.label AHB_textures
// adb shell setprop debug.angle.capture.out_dir /data/data/AHBtextures/angle_capture/
TEST_P(ImageTest, AppTraceExternalTextureWithAHBUseCase)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());

    GLubyte data[4] = {7, 51, 197, 231};

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {{data, 4}},
                                              &source, &image);

    // Create a texture target to bind the egl image & disable mipmapping
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    // Calls On EndFrame(), with MidExecutionSetup to restore external target texture above
    EGLDisplay display = getEGLWindow()->getDisplay();
    EGLSurface surface = getEGLWindow()->getSurface();
    eglSwapBuffers(display, surface);

    // Create another eglImage with another associated texture
    // Draw using the eglImage target texture created in frame 1
    AHardwareBuffer *source2;
    EGLImageKHR image2;
    createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                              kDefaultAHBUsage, kDefaultAttribs, {{data, 4}},
                                              &source2, &image2);

    // Create another texture target to bind the egl image & disable mipmapping
    GLTexture target2;
    createEGLImageTargetTextureExternal(image, target2);

    glUseProgram(mTextureExternalProgram);
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, target);
    glUniform1i(mTextureExternalUniformLocation, 0);

    drawQuad(mTextureExternalProgram, "position", 0.5f);

    // Calls On EndFrame() to save the gl calls creating external texture target2;
    // We use this as a reference to check the gl calls we restore for GLTexture target
    // in MidExecutionSetup
    eglSwapBuffers(display, surface);

    // Draw a quad with the GLTexture target2
    glUseProgram(mTextureExternalProgram);
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, target2);
    glUniform1i(mTextureExternalUniformLocation, 0);

    drawQuad(mTextureExternalProgram, "position", 0.5f);

    eglSwapBuffers(display, surface);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
    eglDestroyImageKHR(window->getDisplay(), image2);
}

// Thread 0 creates the AHB and binds it to a texture, thread 1 uses it without synchronization.
TEST_P(ImageTest, MultithreadedAHBImportAndUseAsTexture)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    EGLWindow *window = getEGLWindow();

    GLuint sharedTexture = 0;

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;

    constexpr GLubyte kInitialData[4] = {127, 63, 191, 255};

    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread0CreatedTexture,
        Thread1UsedTexture,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                                  kDefaultAHBUsage, kDefaultAttribs,
                                                  {{kInitialData, 4}}, &source, &image);
        ASSERT_GL_NO_ERROR();

        GLTexture texture;
        sharedTexture = texture;

        createEGLImageTargetTextureExternal(image, sharedTexture);
        ASSERT_GL_NO_ERROR();

        // Wait for the other thread to use it.
        threadSynchronization.nextStep(Step::Thread0CreatedTexture);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1UsedTexture));

        eglDestroyImageKHR(window->getDisplay(), image);
        texture.reset();

        threadSynchronization.nextStep(Step::Finish);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    };

    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Wait for thread 0 to set up
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0CreatedTexture));

        // Sample from the texture
        ANGLE_GL_PROGRAM(drawTexture, getVS(), getTextureExternalFS());
        glUseProgram(drawTexture);
        glBindTexture(GL_TEXTURE_EXTERNAL_OES, sharedTexture);
        glUniform1i(mTextureExternalUniformLocation, 0);
        ASSERT_GL_NO_ERROR();

        drawQuad(drawTexture, "position", 0.5f);
        ASSERT_GL_NO_ERROR();

        // Make a submission
        EXPECT_PIXEL_COLOR_NEAR(
            0, 0, GLColor(kInitialData[0], kInitialData[1], kInitialData[2], kInitialData[3]), 1);

        // Notify the other thread that it's finished using the texture.
        threadSynchronization.nextStep(Step::Thread1UsedTexture);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    };

    std::array<LockStepThreadFunc, 2> threadFuncs = {
        std::move(thread0),
        std::move(thread1),
    };

    RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data());

    ASSERT_NE(currentStep, Step::Abort);
}

// Thread 0 creates the AHB and binds it to a renderbuffer, thread 1 uses it without
// synchronization.
TEST_P(ImageTest, MultithreadedAHBImportAndUseAsRenderbuffer)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !hasRenderbufferExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!hasAhbLockPlanesSupport());
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    EGLWindow *window = getEGLWindow();

    GLuint sharedRenderbuffer = 0;

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;

    constexpr GLubyte kInitialData[4] = {127, 63, 191, 255};

    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread0CreatedRenderbuffer,
        Thread1UsedRenderbuffer,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        createEGLImageAndroidHardwareBufferSource(1, 1, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
                                                  kDefaultAHBUsage, kDefaultAttribs,
                                                  {{kInitialData, 4}}, &source, &image);
        ASSERT_GL_NO_ERROR();

        GLRenderbuffer renderbuffer;
        sharedRenderbuffer = renderbuffer;

        createEGLImageTargetRenderbuffer(image, sharedRenderbuffer);
        ASSERT_GL_NO_ERROR();

        // Wait for the other thread to use it.
        threadSynchronization.nextStep(Step::Thread0CreatedRenderbuffer);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1UsedRenderbuffer));

        eglDestroyImageKHR(window->getDisplay(), image);
        renderbuffer.reset();

        threadSynchronization.nextStep(Step::Finish);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    };

    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Wait for thread 0 to set up
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0CreatedRenderbuffer));

        // Blend into the renderbuffer
        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
                                  sharedRenderbuffer);
        EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
        ASSERT_GL_NO_ERROR();

        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);

        ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
        drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.5f);
        ASSERT_GL_NO_ERROR();

        // Make a submission
        EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(255, kInitialData[1], kInitialData[2], 255), 1);

        // Notify the other thread that it's finished using the renderbuffer.
        threadSynchronization.nextStep(Step::Thread1UsedRenderbuffer);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    };

    std::array<LockStepThreadFunc, 2> threadFuncs = {
        std::move(thread0),
        std::move(thread1),
    };

    RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data());

    ASSERT_NE(currentStep, Step::Abort);
}

void ImageTest::framebufferAttachmentDeletedWhileInUseHelper(bool useTextureAttachment,
                                                             bool deleteSourceTextureLast)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt());
    ANGLE_SKIP_TEST_IF(useTextureAttachment && !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!useTextureAttachment && !hasRenderbufferExt());
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    EGLWindow *window = getEGLWindow();
    EGLImageKHR image = EGL_NO_IMAGE_KHR;

    std::mutex mutex;
    std::condition_variable condVar;
    EGLSyncKHR sync;

    enum class Step
    {
        Start,
        Thread0CreatedImage,
        Thread1UsedImage,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    EXPECT_EGL_TRUE(window->makeCurrent(EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

    // This thread will use window context
    std::thread thread0([&]() {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        window->makeCurrent();

        // Create the Image
        GLTexture source;
        createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs,
                                      kLinearColor, source, &image);

        sync = eglCreateSyncKHR(window->getDisplay(), EGL_SYNC_FENCE_KHR, nullptr);
        ASSERT_GL_NO_ERROR();

        // Wait thread 1 finish using the Image
        threadSynchronization.nextStep(Step::Thread0CreatedImage);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1UsedImage));

        if (!deleteSourceTextureLast)
        {
            // Delete "source" texture first - image buffer will be deleted with the "image"
            source.reset();
        }

        // Destroy Image
        eglDestroyImageKHR(window->getDisplay(), image);

        if (deleteSourceTextureLast)
        {
            // Delete "source" texture last - this will delete image buffer
            source.reset();
        }

        threadSynchronization.nextStep(Step::Finish);

        EXPECT_EGL_TRUE(window->makeCurrent(EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    });

    // This thread will use non Shared context
    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0CreatedImage));

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));
        eglWaitSyncKHR(dpy, sync, 0);

        // Create the target and set up a framebuffer to render into the Image
        GLFramebuffer fbo;
        GLTexture targetTexture;
        GLRenderbuffer targetRenderbuffer;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        if (useTextureAttachment)
        {
            createEGLImageTargetTexture2D(image, targetTexture);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                   targetTexture, 0);
        }
        else
        {
            createEGLImageTargetRenderbuffer(image, targetRenderbuffer);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
                                      targetRenderbuffer);
        }
        EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        // Test that framebuffer has source content
        EXPECT_PIXEL_EQ(0, 0, kLinearColor[0], kLinearColor[1], kLinearColor[2], kLinearColor[3]);

        // Create additional target texture
        GLTexture targetTexture2;
        createEGLImageTargetTexture2D(image, targetTexture2);

        // Enable additive blend
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);

        // Draw Red quad into the framebuffer
        ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
        drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.0f);
        ASSERT_GL_NO_ERROR();

        // Delete "targetTexture2" that may affect RenderPass because it uses same Image
        targetTexture2.reset();

        // Clear previous draw
        glClearColor(128 / 255.0f, 128 / 255.0f, 128 / 255.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // Draw Green quad into the framebuffer
        ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
        drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.0f);
        ASSERT_GL_NO_ERROR();

        // Test that clear and second draw worked as expected
        EXPECT_PIXEL_EQ(0, 0, 128, 255, 128, 255);

        // Draw again to open RenderPass after the read pixels
        drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.0f);
        ASSERT_GL_NO_ERROR();

        // Delete resources
        fbo.reset();
        targetTexture.reset();
        targetRenderbuffer.reset();
        ASSERT_GL_NO_ERROR();

        // Wait thread 0 destroys the Image and source
        threadSynchronization.nextStep(Step::Thread1UsedImage);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    };

    std::array<LockStepThreadFunc, 1> threadFuncs = {
        std::move(thread1),
    };

    RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data());
    thread0.join();

    window->makeCurrent();

    ASSERT_NE(currentStep, Step::Abort);
}

// Testing Target 2D Texture deleted while still used in the RenderPass (Image destroyed last).
TEST_P(ImageTest, TargetTexture2DDeletedWhileInUse)
{
    framebufferAttachmentDeletedWhileInUseHelper(true, false);
}

// Testing Target 2D Texture deleted while still used in the RenderPass (Source deleted last).
TEST_P(ImageTest, TargetTexture2DDeletedWhileInUse2)
{
    framebufferAttachmentDeletedWhileInUseHelper(true, true);
}

// Testing Target Renderbuffer deleted while still used in the RenderPass (Image destroyed last).
TEST_P(ImageTest, TargetRenderbufferDeletedWhileInUse)
{
    framebufferAttachmentDeletedWhileInUseHelper(false, false);
}

// Testing Target Renderbuffer deleted while still used in the RenderPass (Source deleted last).
TEST_P(ImageTest, TargetRenderbufferDeletedWhileInUse2)
{
    framebufferAttachmentDeletedWhileInUseHelper(false, true);
}

void ImageTest::framebufferResolveAttachmentDeletedWhileInUseHelper(bool useTextureAttachment,
                                                                    bool deleteSourceTextureLast)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt());
    ANGLE_SKIP_TEST_IF(useTextureAttachment && !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!useTextureAttachment && !hasRenderbufferExt());
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    EGLWindow *window = getEGLWindow();
    EGLImageKHR image = EGL_NO_IMAGE_KHR;

    std::mutex mutex;
    std::condition_variable condVar;
    EGLSyncKHR sync;

    enum class Step
    {
        Start,
        Thread0CreatedImage,
        Thread1UsedImage,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    EXPECT_EGL_TRUE(window->makeCurrent(EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

    // This thread will use window context
    std::thread thread0([&]() {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        window->makeCurrent();

        // Create the Image
        GLTexture source;
        createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs,
                                      kLinearColor, source, &image);

        sync = eglCreateSyncKHR(window->getDisplay(), EGL_SYNC_FENCE_KHR, nullptr);
        ASSERT_GL_NO_ERROR();

        // Wait thread 1 finish using the Image
        threadSynchronization.nextStep(Step::Thread0CreatedImage);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1UsedImage));

        if (!deleteSourceTextureLast)
        {
            // Delete "source" texture first - image buffer will be deleted with the "image"
            source.reset();
        }

        // Destroy Image
        eglDestroyImageKHR(window->getDisplay(), image);

        if (deleteSourceTextureLast)
        {
            // Delete "source" texture last - this will delete image buffer
            source.reset();
        }

        threadSynchronization.nextStep(Step::Finish);

        EXPECT_EGL_TRUE(window->makeCurrent(EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    });

    // This thread will use non Shared context
    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0CreatedImage));

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));
        eglWaitSyncKHR(dpy, sync, 0);

        // Create the target and set up a framebuffer to render into the Image
        GLFramebuffer fbo;
        GLTexture targetTexture;
        GLRenderbuffer targetRenderbuffer;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        if (useTextureAttachment)
        {
            createEGLImageTargetTexture2D(image, targetTexture);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                   targetTexture, 0);
        }
        else
        {
            createEGLImageTargetRenderbuffer(image, targetRenderbuffer);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
                                      targetRenderbuffer);
        }
        EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        // Test that framebuffer has source content
        EXPECT_PIXEL_EQ(0, 0, kLinearColor[0], kLinearColor[1], kLinearColor[2], kLinearColor[3]);

        // Create additional target texture
        GLTexture targetTexture2;
        createEGLImageTargetTexture2D(image, targetTexture2);

        // Create MSAA framebuffer
        GLTexture msaaColor;
        glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, msaaColor);
        glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, 1, 1, false);

        GLFramebuffer msaaFBO;
        glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
                               msaaColor, 0);
        ASSERT_GL_NO_ERROR();
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        // Draw Red quad into the MSAA framebuffer
        ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
        drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.0f);
        ASSERT_GL_NO_ERROR();

        // Resolve into image
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
        glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
        ASSERT_GL_NO_ERROR();

        // Delete "targetTexture2" that may affect RenderPass because it uses same Image
        targetTexture2.reset();

        // Start another render pass and blend into the image.
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);

        ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
        drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.0f);
        ASSERT_GL_NO_ERROR();

        // Test that resolve and draw worked
        glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);

        // Draw again to open RenderPass after the read pixels
        glDisable(GL_BLEND);
        drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.0f);
        ASSERT_GL_NO_ERROR();

        // Delete resources
        fbo.reset();
        targetTexture.reset();
        targetRenderbuffer.reset();
        ASSERT_GL_NO_ERROR();

        // Wait thread 0 destroys the Image and source
        threadSynchronization.nextStep(Step::Thread1UsedImage);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    };

    std::array<LockStepThreadFunc, 1> threadFuncs = {
        std::move(thread1),
    };

    RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data());
    thread0.join();

    window->makeCurrent();

    ASSERT_NE(currentStep, Step::Abort);
}

// Test whether the dimension size of the target GL_TEXTURE_EXTERNAL_OES is as expected.
TEST_P(ImageTestES31, QueryDimFromExternalTex)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt() || !hasExternalExt());

    // Create the Image
    GLTexture source;
    GLsizei src_w = 1, src_h = 1, qw = 0, qh = 0;
    EGLImageKHR image;
    createEGLImage2DTextureSource(src_w, src_h, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs,
                                  kSrgbColor, source, &image);

    // Create the target
    GLTexture target;
    createEGLImageTargetTextureExternal(image, target);

    // Querying the dimensions should work
    glGetTexLevelParameteriv(GL_TEXTURE_EXTERNAL_OES, 0, GL_TEXTURE_WIDTH, &qw);
    EXPECT_EQ(qw, src_w);
    glGetTexLevelParameteriv(GL_TEXTURE_EXTERNAL_OES, 0, GL_TEXTURE_HEIGHT, &qh);
    EXPECT_EQ(qh, src_h);

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Testing Target 2D Texture deleted while still used in the RenderPass as resolve attachment (Image
// destroyed last).
TEST_P(ImageTestES31, TargetTexture2DDeletedWhileInUseAsResolve)
{
    framebufferResolveAttachmentDeletedWhileInUseHelper(true, false);
}

// Testing Target 2D Texture deleted while still used in the RenderPass as resolve attachment
// (Source deleted last).
TEST_P(ImageTestES31, TargetTexture2DDeletedWhileInUseAsResolve2)
{
    framebufferResolveAttachmentDeletedWhileInUseHelper(true, true);
}

// Testing Target Renderbuffer deleted while still used in the RenderPass as resolve attachment
// (Image destroyed last).
TEST_P(ImageTestES31, TargetRenderbufferDeletedWhileInUseAsResolve)
{
    framebufferResolveAttachmentDeletedWhileInUseHelper(false, false);
}

// Testing Target Renderbuffer deleted while still used in the RenderPass as resolve attachment
// (Source deleted last).
TEST_P(ImageTestES31, TargetRenderbufferDeletedWhileInUseAsResolve2)
{
    framebufferResolveAttachmentDeletedWhileInUseHelper(false, true);
}

// Test that the AHB can be used in some way in GL, then accessed by foreign entity, then used again
// by GL.  This makes sure transitions in and out of the FOREIGN Vulkan queue are correctly
// implemented.
void ImageTest::useAHBByGLThenForeignThenGLHelper(
    std::function<void(const GLTexture &, uint32_t, uint32_t)> firstUse,
    std::function<void(const GLTexture &, uint32_t, uint32_t)> secondUse)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !hasRenderbufferExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    constexpr uint32_t kWidth  = 53;
    constexpr uint32_t kHeight = 37;

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(
        kWidth, kHeight, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, kDefaultAHBUsage,
        kDefaultAttribs, {}, &source, &image);

    // Create a texture target to bind the egl image
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    glViewport(0, 0, kWidth, kHeight);

    // Use the image in GL once.
    firstUse(target, kWidth, kHeight);

    // In between uses, overwrite parts of the image.
    // First, wait for first use to finish.
    EGLWindow *window = getEGLWindow();
    EGLSyncKHR fence  = eglCreateSyncKHR(window->getDisplay(), EGL_SYNC_FENCE_KHR, NULL);
    glFlush();
    EGLint result = eglClientWaitSyncKHR(window->getDisplay(), fence, 0, 1'000'000'000);
    ASSERT_EQ(result, EGL_CONDITION_SATISFIED_KHR);
    ASSERT_EGL_TRUE(eglDestroySyncKHR(window->getDisplay(), fence));

    // Then overwrite a quarter of the image with some color
    std::vector<GLubyte> data((kWidth / 2) * (kHeight / 2) * 4, 99);
    writeAHBData(source, kWidth / 2, kHeight / 2, 1, false, {{data.data(), 4}});

    // And use the image again in GL.
    secondUse(target, kWidth, kHeight);

    ASSERT_GL_NO_ERROR();
}

// Test draw, use in foreign, then draw again
TEST_P(ImageTest, DrawForeignDraw)
{
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    auto first = [&](const GLTexture &texture, uint32_t width, uint32_t height) {
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
    };
    auto second = [&](const GLTexture &texture, uint32_t width, uint32_t height) {
        glBindTexture(GL_TEXTURE_2D, texture);

        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);

        glEnable(GL_SCISSOR_TEST);
        glScissor(width / 4, 0, width / 2, height);

        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);

        // Expect the following:
        //
        // +-----+-----+-----+-----+
        // |     |     |     |     |
        // | 99  | 99  | G   | G   |
        // |     | +   | +   |     |
        // |     | R   | R   |     |
        // |     |     |     |     |
        // +-----+-----+-----+     |
        // |     |           |     |
        // | G   | G + R     | G   |
        // |     |           |     |
        // |     |           |     |
        // |     |           |     |
        // +-----+-----------+-----+
        //
        EXPECT_PIXEL_RECT_EQ(0, 0, width / 4, height / 2, GLColor(99, 99, 99, 99));
        EXPECT_PIXEL_RECT_EQ(0, height / 2, width / 4, height - height / 2, GLColor::green);
        EXPECT_PIXEL_RECT_EQ(width / 4, 0, width / 2 - width / 4, height / 2,
                             GLColor(255, 99, 99, 255));
        EXPECT_PIXEL_RECT_EQ(width / 4, height / 2, width / 2, height - height / 2,
                             GLColor::yellow);
        EXPECT_PIXEL_RECT_EQ(width / 2, 0, width / 2 - width / 4, height / 2, GLColor::yellow);
        EXPECT_PIXEL_RECT_EQ(width / 4 + width / 2, 0, width - width / 2 - width / 4, height,
                             GLColor::green);
    };

    useAHBByGLThenForeignThenGLHelper(first, second);
}

// Test draw, use in foreign, then blit
TEST_P(ImageTestES3, DrawForeignBlit)
{
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    auto first = [&](const GLTexture &texture, uint32_t width, uint32_t height) {
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
    };
    auto second = [&](const GLTexture &texture, uint32_t width, uint32_t height) {
        GLFramebuffer otherFbo;
        glBindFramebuffer(GL_FRAMEBUFFER, otherFbo);

        GLTexture color;
        glBindTexture(GL_TEXTURE_2D, color);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     nullptr);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        glClearColor(0, 0, 1, 1);
        glClear(GL_COLOR_BUFFER_BIT);

        glBindTexture(GL_TEXTURE_2D, texture);
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);

        glBlitFramebuffer(width / 4, 0, width / 2 + width / 4, height, width / 4, 0,
                          width / 2 + width / 4, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
        glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);

        // Expect the following:
        //
        // +-----+-----------+-----+
        // |     |           |     |
        // | 99  | B         | G   |
        // |     |           |     |
        // |     |           |     |
        // |     |           |     |
        // +-----+           |     |
        // |     |           |     |
        // | G   |           |     |
        // |     |           |     |
        // |     |           |     |
        // |     |           |     |
        // +-----+-----------+-----+
        //
        EXPECT_PIXEL_RECT_EQ(0, 0, width / 4, height / 2, GLColor(99, 99, 99, 99));
        EXPECT_PIXEL_RECT_EQ(0, height / 2, width / 4, height - height / 2, GLColor::green);
        EXPECT_PIXEL_RECT_EQ(width / 4, 0, width / 2 - width / 4, height, GLColor::blue);
        EXPECT_PIXEL_RECT_EQ(width / 4 + width / 2, 0, width - width / 2 - width / 4, height,
                             GLColor::green);
    };

    useAHBByGLThenForeignThenGLHelper(first, second);
}

// Test draw, readback, use in foreign, then draw again
TEST_P(ImageTest, DrawReadbackForeignDraw)
{
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    auto first = [&](const GLTexture &texture, uint32_t width, uint32_t height) {
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);

        // A second usage of the same image
        EXPECT_PIXEL_RECT_EQ(0, 0, width, height, GLColor::green);
    };
    auto second = [&](const GLTexture &texture, uint32_t width, uint32_t height) {
        glBindTexture(GL_TEXTURE_2D, texture);

        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);

        glEnable(GL_SCISSOR_TEST);
        glScissor(width / 4, 0, width / 2, height);

        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);

        // Expect the following:
        //
        // +-----+-----+-----+-----+
        // |     |     |     |     |
        // | 99  | 99  | G   | G   |
        // |     | +   | +   |     |
        // |     | R   | R   |     |
        // |     |     |     |     |
        // +-----+-----+-----+     |
        // |     |           |     |
        // | G   | G + R     | G   |
        // |     |           |     |
        // |     |           |     |
        // |     |           |     |
        // +-----+-----------+-----+
        //
        EXPECT_PIXEL_RECT_EQ(0, 0, width / 4, height / 2, GLColor(99, 99, 99, 99));
        EXPECT_PIXEL_RECT_EQ(0, height / 2, width / 4, height - height / 2, GLColor::green);
        EXPECT_PIXEL_RECT_EQ(width / 4, 0, width / 2 - width / 4, height / 2,
                             GLColor(255, 99, 99, 255));
        EXPECT_PIXEL_RECT_EQ(width / 4, height / 2, width / 2, height - height / 2,
                             GLColor::yellow);
        EXPECT_PIXEL_RECT_EQ(width / 2, 0, width / 2 - width / 4, height / 2, GLColor::yellow);
        EXPECT_PIXEL_RECT_EQ(width / 4 + width / 2, 0, width - width / 2 - width / 4, height,
                             GLColor::green);
    };

    useAHBByGLThenForeignThenGLHelper(first, second);
}

// Test draw, use in foreign, then readback
TEST_P(ImageTest, DrawForeignReadback)
{
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    auto first = [&](const GLTexture &texture, uint32_t width, uint32_t height) {
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
    };
    auto second = [&](const GLTexture &texture, uint32_t width, uint32_t height) {
        glBindTexture(GL_TEXTURE_2D, texture);

        // Expect the following:
        //
        // +-----------+-----------+
        // |           |           |
        // | 99        |           |
        // |           |           |
        // |           |           |
        // |           |           |
        // +-----------+           |
        // |                       |
        // | G                     |
        // |                       |
        // |                       |
        // |                       |
        // +-----------------------+
        //
        EXPECT_PIXEL_RECT_EQ(0, 0, width / 2, height / 2, GLColor(99, 99, 99, 99));
        EXPECT_PIXEL_RECT_EQ(width / 2, 0, width - width / 2, height / 2, GLColor::green);
        EXPECT_PIXEL_RECT_EQ(0, height / 2, width, height - height / 2, GLColor::green);
    };

    useAHBByGLThenForeignThenGLHelper(first, second);
}

// Test use as resolve attachment, use in foreign, then draw again
TEST_P(ImageTestES3, ResolveForeignDraw)
{
    GLFramebuffer fbo;

    auto first = [&](const GLTexture &texture, uint32_t width, uint32_t height) {
        GLRenderbuffer color;
        glBindRenderbuffer(GL_RENDERBUFFER, color);
        glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, width, height);

        GLFramebuffer msaaFbo;
        glBindFramebuffer(GL_FRAMEBUFFER, msaaFbo);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);

        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture,
                               0);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);

        glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT,
                          GL_NEAREST);
        glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
    };
    auto second = [&](const GLTexture &texture, uint32_t width, uint32_t height) {
        glBindTexture(GL_TEXTURE_2D, texture);

        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);

        glEnable(GL_SCISSOR_TEST);
        glScissor(width / 4, 0, width / 2, height);

        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);

        // Expect the following:
        //
        // +-----+-----+-----+-----+
        // |     |     |     |     |
        // | 99  | 99  | G   | G   |
        // |     | +   | +   |     |
        // |     | R   | R   |     |
        // |     |     |     |     |
        // +-----+-----+-----+     |
        // |     |           |     |
        // | G   | G + R     | G   |
        // |     |           |     |
        // |     |           |     |
        // |     |           |     |
        // +-----+-----------+-----+
        //
        EXPECT_PIXEL_RECT_EQ(0, 0, width / 4, height / 2, GLColor(99, 99, 99, 99));
        EXPECT_PIXEL_RECT_EQ(0, height / 2, width / 4, height - height / 2, GLColor::green);
        EXPECT_PIXEL_RECT_EQ(width / 4, 0, width / 2 - width / 4, height / 2,
                             GLColor(255, 99, 99, 255));
        EXPECT_PIXEL_RECT_EQ(width / 4, height / 2, width / 2, height - height / 2,
                             GLColor::yellow);
        EXPECT_PIXEL_RECT_EQ(width / 2, 0, width / 2 - width / 4, height / 2, GLColor::yellow);
        EXPECT_PIXEL_RECT_EQ(width / 4 + width / 2, 0, width - width / 2 - width / 4, height,
                             GLColor::green);
    };

    useAHBByGLThenForeignThenGLHelper(first, second);
}

// Tests that uploading to a foreign image until the outside RP command buffer is submitted does not
// break the render pass.
TEST_P(ImageTest, UploadForeignUntilSubmitDoesNotBreakRenderPass)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !hasRenderbufferExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());

    constexpr size_t kMaxBufferToImageCopySize = 64 * 1024 * 1024;
    constexpr uint64_t kNumOutsideSubmits      = 1;
    constexpr uint32_t kWidth                  = 53;
    constexpr uint32_t kHeight                 = 37;

    ANGLE_GL_PROGRAM(drawTextureProgram, essl1_shaders::vs::Texture2D(),
                     essl1_shaders::fs::Texture2D());
    glUseProgram(drawTextureProgram);
    GLint texLocation = glGetUniformLocation(drawTextureProgram, essl1_shaders::Texture2DUniform());
    ASSERT_NE(-1, texLocation);
    glUniform1i(texLocation, 0);

    // Set up FBO.
    GLFramebuffer fbo;
    GLTexture colorTexFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glBindTexture(GL_TEXTURE_2D, colorTexFBO);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexFBO, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    glViewport(0, 0, kWidth, kHeight);

    // Create the EGL image and a texture target to bind it.
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(
        kWidth, kHeight, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, kDefaultAHBUsage,
        kDefaultAttribs, {}, &source, &image);

    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Use the image in GL once.
    glBindTexture(GL_TEXTURE_2D, target);
    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);

    std::vector<GLColor> kDrawData1(kWidth * kHeight, GLColor::blue);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
                    kDrawData1.data());
    drawQuad(drawTextureProgram, essl1_shaders::PositionAttrib(), 0.5f);

    // Upload data to and draw with a temp texture. In the Vulkan backend, the data may get flushed
    // without closing the render pass.
    // The draw will be limited to one pixel via glScissor().
    std::vector<GLColor> kDrawData2(kWidth * kHeight, GLColor::green);
    glEnable(GL_SCISSOR_TEST);
    glScissor(0, 0, 1, 1);

    constexpr size_t kMaxLoadCount =
        kMaxBufferToImageCopySize / (kWidth * kHeight * 4) * kNumOutsideSubmits + 1;
    for (size_t loadCount = 0; loadCount < kMaxLoadCount; loadCount++)
    {
        GLTexture tempTexture;
        glBindTexture(GL_TEXTURE_2D, tempTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     kDrawData2.data());
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        drawQuad(drawTextureProgram, essl1_shaders::PositionAttrib(), 0.5f);
        ASSERT_GL_NO_ERROR();
    }

    // Verify the draws.
    EXPECT_PIXEL_RECT_EQ(1, 0, kWidth - 1, kHeight, GLColor::blue);
    EXPECT_PIXEL_RECT_EQ(0, 1, kWidth, kHeight - 1, GLColor::blue);
    EXPECT_PIXEL_RECT_EQ(0, 0, 1, 1, GLColor::green);

    glDisable(GL_SCISSOR_TEST);
    ASSERT_GL_NO_ERROR();
}

// Tests that copying to a foreign image until the outside RP command buffer is submitted does not
// break the render pass.
TEST_P(ImageTest, CopyToForeignUntilSubmitDoesNotBreakRenderPass)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !hasRenderbufferExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_copy_image"));

    constexpr size_t kMaxBufferToImageCopySize = 64 * 1024 * 1024;
    constexpr uint64_t kNumOutsideSubmits      = 1;
    constexpr uint32_t kWidth                  = 53;
    constexpr uint32_t kHeight                 = 37;

    ANGLE_GL_PROGRAM(drawTextureProgram, essl1_shaders::vs::Texture2D(),
                     essl1_shaders::fs::Texture2D());
    glUseProgram(drawTextureProgram);
    GLint texLocation = glGetUniformLocation(drawTextureProgram, essl1_shaders::Texture2DUniform());
    ASSERT_NE(-1, texLocation);
    glUniform1i(texLocation, 0);

    // Set up FBO.
    GLFramebuffer fbo;
    GLTexture colorTexFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glBindTexture(GL_TEXTURE_2D, colorTexFBO);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexFBO, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    glViewport(0, 0, kWidth, kHeight);

    // Create the EGL images and the texture targets to bind them.
    AHardwareBuffer *source1;
    EGLImageKHR image1;
    createEGLImageAndroidHardwareBufferSource(
        kWidth, kHeight, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, kDefaultAHBUsage,
        kDefaultAttribs, {}, &source1, &image1);

    GLTexture target1;
    createEGLImageTargetTexture2D(image1, target1);

    AHardwareBuffer *source2;
    EGLImageKHR image2;
    createEGLImageAndroidHardwareBufferSource(
        kWidth, kHeight, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, kDefaultAHBUsage,
        kDefaultAttribs, {}, &source2, &image2);

    GLTexture target2;
    createEGLImageTargetTexture2D(image2, target2);

    // Use the first image in GL.
    glBindTexture(GL_TEXTURE_2D, target1);
    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);

    std::vector<GLColor> kDrawData(kWidth * kHeight, GLColor::blue);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
                    kDrawData.data());
    drawQuad(drawTextureProgram, essl1_shaders::PositionAttrib(), 0.5f);

    // Copy to the second image in GL.
    std::vector<GLColor> kCopyData(kWidth * kHeight, GLColor::green);
    constexpr size_t kMaxLoadCount =
        kMaxBufferToImageCopySize / (kWidth * kHeight * 4) * kNumOutsideSubmits + 1;

    for (size_t loadCount = 0; loadCount < kMaxLoadCount; loadCount++)
    {
        GLTexture tempTexture;
        glBindTexture(GL_TEXTURE_2D, tempTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     kCopyData.data());
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        glCopyImageSubDataEXT(tempTexture, GL_TEXTURE_2D, 0, 0, 0, 0, target2, GL_TEXTURE_2D, 0, 0,
                              0, 0, kWidth, kHeight, 1);
        ASSERT_GL_NO_ERROR();
    }

    // Verify the draw.
    EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::blue);
}

// Test upload, use in foreign, then draw
TEST_P(ImageTest, UploadForeignDraw)
{
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    auto first = [&](const GLTexture &texture, uint32_t width, uint32_t height) {
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        std::vector<GLColor> data(width * height, GLColor::blue);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
                        data.data());

        EXPECT_PIXEL_RECT_EQ(0, 0, width, height, GLColor::blue);
    };
    auto second = [&](const GLTexture &texture, uint32_t width, uint32_t height) {
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);

        glEnable(GL_SCISSOR_TEST);
        glScissor(width / 4, 0, width / 2, height);

        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);

        // Expect the following:
        //
        // +-----+-----+-----+-----+
        // |     |     |     |     |
        // | 99  | 99  | B   | B   |
        // |     | +   | +   |     |
        // |     | R   | R   |     |
        // |     |     |     |     |
        // +-----+-----+-----+     |
        // |     |           |     |
        // | B   | B + R     | B   |
        // |     |           |     |
        // |     |           |     |
        // |     |           |     |
        // +-----+-----------+-----+
        //
        EXPECT_PIXEL_RECT_EQ(0, 0, width / 4, height / 2, GLColor(99, 99, 99, 99));
        EXPECT_PIXEL_RECT_EQ(0, height / 2, width / 4, height - height / 2, GLColor::blue);
        EXPECT_PIXEL_RECT_EQ(width / 4, 0, width / 2 - width / 4, height / 2,
                             GLColor(255, 99, 99, 255));
        EXPECT_PIXEL_RECT_EQ(width / 4, height / 2, width / 2, height - height / 2,
                             GLColor::magenta);
        EXPECT_PIXEL_RECT_EQ(width / 2, 0, width / 2 - width / 4, height / 2, GLColor::magenta);
        EXPECT_PIXEL_RECT_EQ(width / 4 + width / 2, 0, width - width / 2 - width / 4, height,
                             GLColor::blue);
    };

    useAHBByGLThenForeignThenGLHelper(first, second);
}

// Test sample in FS, use in foreign, then sample again in VS
TEST_P(ImageTestES3, SampleForeignSample)
{
    GLTexture color;

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    auto first = [&](const GLTexture &texture, uint32_t width, uint32_t height) {
        glBindTexture(GL_TEXTURE_2D, color);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     nullptr);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        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);

        std::vector<GLColor> data(width * height, GLColor::blue);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
                        data.data());

        ANGLE_GL_PROGRAM(drawTexture, essl1_shaders::vs::Texture2D(),
                         essl1_shaders::fs::Texture2D());
        glUseProgram(drawTexture);
        GLint texLocation = glGetUniformLocation(drawTexture, essl1_shaders::Texture2DUniform());
        ASSERT_NE(-1, texLocation);
        glUniform1i(texLocation, 0);
        drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.5f);

        EXPECT_PIXEL_RECT_EQ(0, 0, width, height, GLColor::blue);
    };
    auto second = [&](const GLTexture &texture, uint32_t width, uint32_t height) {
        glBindTexture(GL_TEXTURE_2D, texture);

        constexpr char kVS[] = R"(precision highp float;
uniform highp sampler2D tex;
attribute vec2 position;
varying vec4 color;
void main()
{
    color = texture2D(tex, position * 0.5 + 0.5);
    gl_Position = vec4(position, 0, 1);
})";

        constexpr char kFS[] = R"(precision highp float;
varying vec4 color;
void main()
{
    gl_FragColor = color;
})";

        ANGLE_GL_PROGRAM(program, kVS, kFS);
        glUseProgram(program);
        GLint texLocation = glGetUniformLocation(program, "tex");
        ASSERT_NE(-1, texLocation);
        glUniform1i(texLocation, 0);

        const std::array<Vector3, 12> kVertices = {{
            Vector3(-1.0f, -1.0f, 0.5f),
            Vector3(-1.0f, -0.1f, 0.5f),
            Vector3(-0.1f, -0.1f, 0.5f),

            Vector3(-1.0f, -1.0f, 0.5f),
            Vector3(-0.1f, -0.1f, 0.5f),
            Vector3(-0.1f, -1.0f, 0.5f),

            Vector3(0.1f, -1.0f, 0.5f),
            Vector3(0.1f, -0.1f, 0.5f),
            Vector3(1.0f, -0.1f, 0.5f),

            Vector3(0.1f, -1.0f, 0.5f),
            Vector3(1.0f, -0.1f, 0.5f),
            Vector3(1.0f, -1.0f, 0.5f),
        }};

        GLint positionLocation = glGetAttribLocation(program, "position");
        ASSERT_NE(-1, positionLocation);
        glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, kVertices.data());
        glEnableVertexAttribArray(positionLocation);

        glClearColor(0, 255, 0, 255);
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, 12);

        // Expect the following:
        //
        // +---------+---+---------+
        // |         |   |         |
        // | 99      |   | B       |
        // |         |   |         |
        // |         |   |         |
        // |---------+   +---------|
        // |                       |
        // |                       |
        // | G                     |
        // |                       |
        // |                       |
        // |                       |
        // +-----------------------+
        //
        EXPECT_PIXEL_RECT_EQ(0, 0, width / 2 - width / 10 - 1, height / 2 - height / 10 - 1,
                             GLColor(99, 99, 99, 99));
        EXPECT_PIXEL_RECT_EQ(width / 2 + width / 10 + 1, 0, width - width / 2 - width / 10 - 1,
                             height / 2 - 1, GLColor::blue);
        EXPECT_PIXEL_RECT_EQ(0, height / 2, width, height - height / 2, GLColor::green);
    };

    useAHBByGLThenForeignThenGLHelper(first, second);
}

// Test draw, use in foreign, readback in another context, use in foreign, then sample in the
// original context.
TEST_P(ImageTestES3, MultithreadedDrawForeignReadbackForeignSample)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasAndroidImageNativeBufferExt() || !hasAndroidHardwareBufferSupport());
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    EGLWindow *window = getEGLWindow();

    constexpr uint32_t kWidth  = 53;
    constexpr uint32_t kHeight = 37;

    // Create the Image
    AHardwareBuffer *source;
    EGLImageKHR image;
    createEGLImageAndroidHardwareBufferSource(
        kWidth, kHeight, 1, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, kDefaultAHBUsage,
        kDefaultAttribs, {}, &source, &image);

    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread0DrawDone,
        Thread1ReadbackDone,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Create a texture target to bind the egl image
        GLTexture target;
        createEGLImageTargetTexture2D(image, target);
        ASSERT_GL_NO_ERROR();

        // Draw into the image in this context.
        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target, 0);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        glViewport(0, 0, kWidth, kHeight);
        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
        ASSERT_GL_NO_ERROR();

        EGLSyncKHR fence = eglCreateSyncKHR(window->getDisplay(), EGL_SYNC_FENCE_KHR, NULL);
        glFlush();
        EGLint result = eglClientWaitSyncKHR(window->getDisplay(), fence, 0, 1'000'000'000);
        ASSERT_EQ(result, EGL_CONDITION_SATISFIED_KHR);
        ASSERT_EGL_TRUE(eglDestroySyncKHR(window->getDisplay(), fence));

        // Then overwrite a quarter of the image with some color
        std::vector<GLubyte> data((kWidth / 2) * (kHeight / 2) * 4, 99);
        writeAHBData(source, kWidth / 2, kHeight / 2, 1, false, {{data.data(), 4}});

        // Wait for the other thread to read back from it.
        threadSynchronization.nextStep(Step::Thread0DrawDone);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1ReadbackDone));

        // Create a different framebuffer to render to.
        GLTexture color;
        glBindTexture(GL_TEXTURE_2D, color);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     nullptr);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        // Sample from the image.
        glBindTexture(GL_TEXTURE_2D, target);
        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);

        ANGLE_GL_PROGRAM(drawTexture, essl1_shaders::vs::Texture2D(),
                         essl1_shaders::fs::Texture2D());
        glUseProgram(drawTexture);
        GLint texLocation = glGetUniformLocation(drawTexture, essl1_shaders::Texture2DUniform());
        ASSERT_NE(-1, texLocation);
        glUniform1i(texLocation, 0);
        drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.5f);

        // Expect the following:
        //
        // +-----+-----+-----+-----+
        // |     |     |           |
        // | 123 | 99  |  G        |
        // |     |     |           |
        // |     |     |           |
        // |     |     |           |
        // |     +-----+           |
        // |     |                 |
        // | 123 |                 |
        // |     |                 |
        // |     |                 |
        // |     |                 |
        // +-----+-----------+-----+
        //
        EXPECT_PIXEL_RECT_EQ(0, 0, kWidth / 4, kHeight, GLColor(123, 123, 123, 123));
        EXPECT_PIXEL_RECT_EQ(kWidth / 4, 0, kWidth / 2 - kWidth / 4, kHeight / 2,
                             GLColor(99, 99, 99, 99));
        EXPECT_PIXEL_RECT_EQ(kWidth / 4, kHeight / 2, kWidth / 2 - kWidth / 4,
                             kHeight - kHeight / 2, GLColor::green);
        EXPECT_PIXEL_RECT_EQ(kWidth / 2, 0, kWidth - kWidth / 2, kHeight, GLColor::green);

        eglDestroyImageKHR(window->getDisplay(), image);

        threadSynchronization.nextStep(Step::Finish);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    };

    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Create a texture target to bind the egl image
        GLTexture target;
        createEGLImageTargetTexture2D(image, target);

        // Wait for thread 0 to set up, and rebind the texture.
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0DrawDone));
        glBindTexture(GL_TEXTURE_2D, target);

        // Expect the following:
        //
        // +-----------+-----------+
        // |           |           |
        // | 99        |           |
        // |           |           |
        // |           |           |
        // |           |           |
        // +-----------+           |
        // |                       |
        // | G                     |
        // |                       |
        // |                       |
        // |                       |
        // +-----------------------+
        //
        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target, 0);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        EXPECT_PIXEL_RECT_EQ(0, 0, kWidth / 2, kHeight / 2, GLColor(99, 99, 99, 99));
        EXPECT_PIXEL_RECT_EQ(kWidth / 2, 0, kWidth - kWidth / 2, kHeight / 2, GLColor::green);
        EXPECT_PIXEL_RECT_EQ(0, kHeight / 2, kWidth, kHeight - kHeight / 2, GLColor::green);

        // Then overwrite parts of the image with another color
        std::vector<GLubyte> data((kWidth / 4) * kHeight * 4, 123);
        writeAHBData(source, kWidth / 4, kHeight, 1, false, {{data.data(), 4}});

        // Notify the other thread that it's finished reading back the texture.
        threadSynchronization.nextStep(Step::Thread1ReadbackDone);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    };

    std::array<LockStepThreadFunc, 2> threadFuncs = {
        std::move(thread0),
        std::move(thread1),
    };

    RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data());

    ASSERT_NE(currentStep, Step::Abort);
}

// Test redefining the same GL texture with different EGLImages
TEST_P(ImageTest, RedefineWithMultipleImages)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    GLubyte originalData[4] = {255, 0, 255, 255};
    GLubyte updateData[4]   = {0, 255, 0, 255};

    // Create the Images
    GLTexture source1, source2;
    EGLImageKHR image1, image2;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs, originalData,
                                  source1, &image1);
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs, originalData,
                                  source2, &image2);

    // Create texture & bind to Image
    GLTexture texture;
    createEGLImageTargetTexture2D(image1, texture);

    // Upload some data between the redefinition
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, updateData);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    ASSERT_GL_NO_ERROR();

    glClear(GL_COLOR_BUFFER_BIT);

    // Bind the second image to this texture
    createEGLImageTargetTexture2D(image2, texture);

    // Delete Image
    eglDestroyImageKHR(window->getDisplay(), image1);
    eglDestroyImageKHR(window->getDisplay(), image2);

    ASSERT_EGL_SUCCESS();

    ASSERT_GL_NO_ERROR();
}

// Regression test to check that sRGB texture can be used to create image in sRGB colorspace.
// Also check that creating image using sRGB texture in linear colorspace wouldn't fail.
TEST_P(ImageTestES3, CreatesRGBImages)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_sRGB"));
    ANGLE_SKIP_TEST_IF(!hasImageGLColorspaceExt());
    ANGLE_SKIP_TEST_IF(
        !IsEGLDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_colorspace"));

    std::vector<EGLint> colorSpaces = {EGL_GL_COLORSPACE_SRGB_KHR, EGL_GL_COLORSPACE_LINEAR_KHR};
    constexpr GLsizei kWidth        = 2;
    constexpr GLsizei kHeight       = 2;

    for (size_t i = 0; i < colorSpaces.size(); i++)
    {
        // Create sRGB texture
        GLTexture sRGBTexture;
        glBindTexture(GL_TEXTURE_2D, sRGBTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8, kWidth, kHeight, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, nullptr);
        ASSERT_GL_NO_ERROR();

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        ASSERT_GL_NO_ERROR();

        EGLint createImageAttribs[] = {
            EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_GL_COLORSPACE_KHR, colorSpaces[i], EGL_NONE,
        };

        // Create the Image using sRGB texture
        EGLImageKHR image =
            eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
                              reinterpretHelper<EGLClientBuffer>(sRGBTexture), createImageAttribs);
        ASSERT_EGL_SUCCESS();
        ASSERT_NE(image, EGL_NO_IMAGE_KHR);

        // Clean up
        eglDestroyImageKHR(window->getDisplay(), image);
    }
}

// Regression test to check that sRGB texture can be used to create image in sRGB colorspace.
// Also check that creating image using sRGB texture in linear colorspace wouldn't fail.
TEST_P(ImageTestES3, DmaBufNegativeValidation)
{
    EGLWindow *window = getEGLWindow();
    ANGLE_SKIP_TEST_IF(!hasBaseExt());
    ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(),
                                                     "EGL_EXT_image_dma_buf_import"));

    const EGLint invalidImageAttributeList[][3] = {
        {EGL_YUV_COLOR_SPACE_HINT_EXT, EGL_NONE, EGL_NONE},
        {EGL_SAMPLE_RANGE_HINT_EXT, EGL_NONE, EGL_NONE},
        {EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT, EGL_NONE, EGL_NONE},
        {EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT, EGL_NONE, EGL_NONE},
    };

    EGLImageKHR image;

    for (size_t i = 0; i < 4; i++)
    {
        image = eglCreateImageKHR(window->getDisplay(), EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL,
                                  invalidImageAttributeList[i]);
        ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
        ASSERT_EQ(image, EGL_NO_IMAGE_KHR);
    }
}

// Test redefining the source GL texture
TEST_P(ImageTestES3, RedefineSourceTexture)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    const GLColor originalColor = GLColor::yellow;
    const std::vector<GLColor> updateColor(4, GLColor::blue);

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs,
                                  originalColor.data(), source, &image);

    // Create texture & bind to Image
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Verify that the target texture has the expected color, makes sure everything is synced and
    // |texture| is fully set up.
    verifyResults2D(target, originalColor.data());

    // Change the source texture.  The size is changed to make sure a new image is definitely
    // created for the texture.
    glBindTexture(GL_TEXTURE_2D, source);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, updateColor.data());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);

    // Make sure source is fully set up.
    verifyResults2D(source, updateColor[0].data());

    // Make sure the target still points to the old image.
    verifyResults2D(target, originalColor.data());

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);

    ASSERT_EGL_SUCCESS();
    ASSERT_GL_NO_ERROR();
}

// Test fully overwriting the source GL texture
TEST_P(ImageTestES3, RewriteSourceTexture)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    const GLColor originalColor = GLColor::yellow;
    const GLColor updateColor   = GLColor::blue;

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs,
                                  originalColor.data(), source, &image);

    // Create texture & bind to Image
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Verify that the target texture has the expected color, makes sure everything is synced and
    // |texture| is fully set up.
    verifyResults2D(target, originalColor.data());

    // Upload new data to source texture such that it's completely overwritten.
    glBindTexture(GL_TEXTURE_2D, source);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, updateColor.data());

    // Make sure the target sees the update written to the source texture.
    verifyResults2D(target, updateColor.data());

    // For completeness, check source too
    verifyResults2D(source, updateColor.data());

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);

    ASSERT_EGL_SUCCESS();
    ASSERT_GL_NO_ERROR();
}

// Test orphaning the image by destroying the source texture.
TEST_P(ImageTestES3, DestroySourceTexture)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    const GLColor originalColor = GLColor::yellow;

    // Create the Image
    GLTexture source;
    EGLImageKHR image;
    createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kDefaultAttribs,
                                  originalColor.data(), source, &image);

    // Delete the texture.
    glBindTexture(GL_TEXTURE_2D, 0);
    source.reset();

    // Make sure the image is still valid.
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Verify that the target texture has the expected color, makes sure everything is synced and
    // |texture| is fully set up.
    verifyResults2D(target, originalColor.data());

    // Destroy the texture before the image.
    glBindTexture(GL_TEXTURE_2D, 0);
    target.reset();

    // Finally, destroy the image itself.
    eglDestroyImageKHR(window->getDisplay(), image);

    ASSERT_EGL_SUCCESS();
    ASSERT_GL_NO_ERROR();
}

// Test using the source GL texture as a storage image.  Internally, the Vulkan backend recreates
// the Texture's image backing.
TEST_P(ImageTestES31, UseSourceTextureAsStorageImage)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    const GLColor originalColor = GLColor::yellow;

    // Create the Image, use glTexStorage2D for storage image use later.
    GLTexture source;
    glBindTexture(GL_TEXTURE_2D, source);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalColor.data());

    EGLImageKHR image =
        eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
                          reinterpretHelper<EGLClientBuffer>(source), kDefaultAttribs);
    ASSERT_EGL_SUCCESS();

    // Create texture & bind to Image
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Verify that the target texture has the expected color, makes sure everything is synced and
    // |texture| is fully set up.
    verifyResults2D(target, originalColor.data());

    // Use the source texture as a storage image
    const char kCS[] = R"(#version 310 es
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
layout(rgba8) uniform highp writeonly image2D img;
void main()
{
    imageStore(img, ivec2(0, 0), vec4(0, 0, 1, 1));
})";

    ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
    glUseProgram(program);

    glBindImageTexture(0, source, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
    glDispatchCompute(1, 1, 1);
    EXPECT_GL_NO_ERROR();

    // Make sure the target sees the update written to the source texture.
    glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
    verifyResults2D(target, GLColor::blue.data());

    // For completeness, check source too
    verifyResults2D(source, GLColor::blue.data());

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);

    ASSERT_EGL_SUCCESS();
    ASSERT_GL_NO_ERROR();
}

// Basic test for using an EGL image as storage for compute
// This is similar to the above UseSourceTextureAsStorageImage but is a bit more basic
// and mirrors an application issue.
TEST_P(ImageTestES31, UseEGLImageAsStorage)
{
    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
    ANGLE_SKIP_TEST_IF(!hasEglImageStorageExt());

    EGLWindow *window = getEGLWindow();

    const GLColor originalColor = GLColor::yellow;

    // Create a storage texture, pre-populate with yellow
    GLTexture source;
    glBindTexture(GL_TEXTURE_2D, source);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalColor.data());

    // Create an image bound to our target texture
    EGLImageKHR image =
        eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
                          reinterpretHelper<EGLClientBuffer>(source), kDefaultAttribs);
    ASSERT_EGL_SUCCESS();

    // Create another texture make it a sibling of the original
    GLTexture target;
    glBindTexture(GL_TEXTURE_2D, target);
    glEGLImageTargetTexStorageEXT(GL_TEXTURE_2D, image, nullptr);
    ASSERT_GL_NO_ERROR();

    // Just write blue to the image
    const char kCS[] = R"(#version 310 es
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
layout(rgba8) uniform highp writeonly image2D img;
void main()
{
    imageStore(img, ivec2(0, 0), vec4(0.0, 0.0, 1.0, 1.0));
})";

    ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
    glUseProgram(program);

    // Use the target texture as a storage image
    glBindImageTexture(0, target, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
    // TODO (http://issuetracker.google.com/456806880)
    // Turn this back on when the VVL error is fixed.
    // glDispatchCompute(1, 1, 1);
    EXPECT_GL_NO_ERROR();

    // We want to sample the target texture, so use the appropriate barrier
    glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);

    // Make sure the target sees the update written to the image.
    // TODO (http://issuetracker.google.com/456806880)
    // Turn this back on when the VVL error is fixed.
    // verifyResults2D(target, GLColor::blue.data());

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);

    ASSERT_EGL_SUCCESS();
    ASSERT_GL_NO_ERROR();
}

// Test overwriting the base level and calling glGenerateMipmap on the source GL texture while the
// texture is in use.
TEST_P(ImageTestES3, ImmutableTextureOverwriteBaseLevelAndGenerateMipmapWhileInUse)
{
    EGLWindow *window = getEGLWindow();

    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());

    constexpr char kVS[] = R"(#version 300 es
out vec2 texcoord;
in vec4 position;
void main()
{
    gl_Position = vec4(position.xy, 0.0, 1.0);
    texcoord = (position.xy * 0.5) + 0.5;
})";

    constexpr char kFS[] = R"(#version 300 es
precision highp float;
uniform sampler2D tex;
in vec2 texcoord;
out vec4 fragColor;
void main()
{
    vec4 test = vec4(0.8, 0.8, 0.8, 0.8);
    for (int i = 0; i < 500; i++)
    {
        test = sqrt(test);
    }
    fragColor = texture(tex, texcoord * test.xy);
})";

    constexpr uint32_t kWidth  = 16;
    constexpr uint32_t kHeight = 24;
    const std::vector<GLColor> originalColor(kWidth * kHeight, GLColor::yellow);
    const std::vector<GLColor> updateColor1(kWidth * kHeight, GLColor::red);
    const std::vector<GLColor> updateColor2(kWidth * kHeight, GLColor::green);
    const std::vector<GLColor> updateColor3(kWidth * kHeight, GLColor::blue);
    const std::vector<GLColor> *updateColors[] = {&updateColor1, &updateColor2, &updateColor3};

    // Create the Image, use glTexStorage2D for glGenerateMipmap not to orphan the EGL image.
    GLTexture source;
    glBindTexture(GL_TEXTURE_2D, source);
    glTexStorage2D(GL_TEXTURE_2D, 5, GL_RGBA8, kWidth, kHeight);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
                    originalColor.data());

    EGLImageKHR image =
        eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
                          reinterpretHelper<EGLClientBuffer>(source), kDefaultAttribs);
    ASSERT_EGL_SUCCESS();

    // Create texture & bind to Image
    GLTexture target;
    createEGLImageTargetTexture2D(image, target);

    // Verify that the target texture has the expected color, makes sure everything is synced and
    // |texture| is fully set up.
    verifyResults2D(target, originalColor[0].data());

    ANGLE_GL_PROGRAM(program, kVS, kFS);
    glBindTexture(GL_TEXTURE_2D, source);

    // Use the source texture in an expensive draw call.  Then completely overwrite the base level,
    // then generate mipmap.  Do this multiple times, for any "redefines base level then generates
    // mipmap" tracking heuristics that might trigger recreating the backing image of the texture to
    // make sure the target texture still points to the same backing image.
    for (uint32_t i = 0; i < 13; ++i)
    {
        for (const auto *updateColor : updateColors)
        {
            drawQuad(program, "position", 0.0f);

            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
                            updateColor->data());
            glGenerateMipmap(GL_TEXTURE_2D);
        }
    }

    // http://anglebug.com/410584007
    ANGLE_SKIP_TEST_IF(getEGLWindow()->isFeatureEnabled(Feature::AllowGenerateMipmapWithCompute));

    // Make sure the target sees the update written to the source texture.
    verifyResults2D(target, updateColor3[0].data());

    // For completeness, check source too
    verifyResults2D(source, updateColor3[0].data());

    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);

    ASSERT_EGL_SUCCESS();
    ASSERT_GL_NO_ERROR();
}

ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(ImageTest,
                                       ES3_VULKAN().enable(Feature::AllocateNonZeroMemory));

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ImageTestES3);
ANGLE_INSTANTIATE_TEST_ES3_AND(ImageTestES3, ES3_VULKAN().enable(Feature::AllocateNonZeroMemory));

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ImageTestES31);
ANGLE_INSTANTIATE_TEST_ES31_AND(ImageTestES31,
                                ES31_VULKAN().enable(Feature::AllocateNonZeroMemory));
}  // namespace angle
