//
// Copyright 2019 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.
//
// GetImageTest:
//   Tests for the ANGLE_get_image extension.
//

#include "common/unsafe_buffers.h"
#include "image_util/storeimage.h"
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"

#include "util/random_utils.h"

using namespace angle;

namespace
{
constexpr uint32_t kSize        = 32;
constexpr char kExtensionName[] = "GL_ANGLE_get_image";
constexpr uint32_t kSmallSize   = 2;
constexpr uint8_t kUNormZero    = 0x00;
constexpr uint8_t kUNormHalf    = 0x7F;
constexpr uint8_t kUNormFull    = 0xFF;

class GetImageTest : public ANGLETest<>
{
  public:
    GetImageTest()
    {
        setWindowWidth(kSize);
        setWindowHeight(kSize);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }
};

class GetImageTestNoExtensions : public ANGLETest<>
{
  public:
    GetImageTestNoExtensions() { setExtensionsEnabled(false); }
};

class GetImageTestES1 : public GetImageTest
{
  public:
    GetImageTestES1() {}
};

class GetImageTestES3 : public GetImageTest
{
  public:
    GetImageTestES3() {}
};

class GetImageTestES31 : public GetImageTest
{
  public:
    GetImageTestES31() {}
};

class GetImageTestES32 : public GetImageTest
{
  public:
    GetImageTestES32() {}
};

GLTexture InitTextureWithFormatAndSize(GLenum format, uint32_t size, void *pixelData)
{
    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, format, size, size, 0, format, GL_UNSIGNED_BYTE, pixelData);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    return tex;
}

GLTexture InitTextureWithSize(uint32_t size, void *pixelData)
{
    // Create a simple texture.
    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    return tex;
}

GLTexture InitSimpleTexture()
{
    std::vector<GLColor> pixelData(kSize * kSize, GLColor::red);
    return InitTextureWithSize(kSize, pixelData.data());
}

GLRenderbuffer InitRenderbufferWithSize(uint32_t size)
{
    // Create a simple renderbuffer.
    GLRenderbuffer renderbuf;
    glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, size, size);
    return renderbuf;
}

GLRenderbuffer InitSimpleRenderbuffer()
{
    return InitRenderbufferWithSize(kSize);
}

// Test validation for the extension functions.
TEST_P(GetImageTest, NegativeAPI)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));

    // Draw once with simple texture.
    GLTexture tex = InitSimpleTexture();
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    ASSERT_GL_NO_ERROR();

    // Pack pixels tightly.
    glPixelStorei(GL_PACK_ALIGNMENT, 1);

    // Verify GetTexImage can work with correct parameters.
    std::vector<GLColor> buffer(kSize * kSize);
    glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
    EXPECT_GL_NO_ERROR();

    // Test invalid texture target.
    glGetTexImageANGLE(GL_TEXTURE_CUBE_MAP, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
    EXPECT_GL_ERROR(GL_INVALID_ENUM);

    // Test invalid texture level.
    glGetTexImageANGLE(GL_TEXTURE_2D, -1, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
    EXPECT_GL_ERROR(GL_INVALID_VALUE);
    glGetTexImageANGLE(GL_TEXTURE_2D, 2000, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
    EXPECT_GL_ERROR(GL_INVALID_VALUE);

    // Test invalid format and type.
    glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_NONE, GL_UNSIGNED_BYTE, buffer.data());
    EXPECT_GL_ERROR(GL_INVALID_ENUM);
    glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_NONE, buffer.data());
    EXPECT_GL_ERROR(GL_INVALID_ENUM);

    // Tests GetCompressed on an uncompressed texture.
    glGetCompressedTexImageANGLE(GL_TEXTURE_2D, 0, buffer.data());
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    // Create a simple renderbuffer.
    GLRenderbuffer renderbuf = InitSimpleRenderbuffer();
    ASSERT_GL_NO_ERROR();

    // Verify GetRenderbufferImage can work with correct parameters.
    glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
    EXPECT_GL_NO_ERROR();

    // Test invalid renderbuffer target.
    glGetRenderbufferImageANGLE(GL_TEXTURE_2D, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
    EXPECT_GL_ERROR(GL_INVALID_ENUM);

    // Test invalid renderbuffer format/type.
    glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_NONE, GL_UNSIGNED_BYTE, buffer.data());
    EXPECT_GL_ERROR(GL_INVALID_ENUM);
    glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_NONE, buffer.data());
    EXPECT_GL_ERROR(GL_INVALID_ENUM);

    // Pack buffer tests. Requires ES 3+ or extension.
    if (getClientMajorVersion() >= 3 || IsGLExtensionEnabled("GL_NV_pixel_buffer_object"))
    {
        // Test valid pack buffer.
        GLBuffer packBuffer;
        glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
        glBufferData(GL_PIXEL_PACK_BUFFER, kSize * kSize * sizeof(GLColor), nullptr,
                     GL_STATIC_DRAW);
        glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
        EXPECT_GL_ERROR(GL_INVALID_OPERATION);
        glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
        EXPECT_GL_ERROR(GL_INVALID_OPERATION);

        // Test too small pack buffer.
        glBufferData(GL_PIXEL_PACK_BUFFER, kSize, nullptr, GL_STATIC_DRAW);
        glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
        EXPECT_GL_ERROR(GL_INVALID_OPERATION);
        glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
        EXPECT_GL_ERROR(GL_INVALID_OPERATION);
    }
}

// Simple test for GetTexImage
TEST_P(GetImageTest, GetTexImage)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));

    std::vector<GLColor> expectedData = {GLColor::red, GLColor::blue, GLColor::green,
                                         GLColor::yellow};

    glViewport(0, 0, kSmallSize, kSmallSize);

    // Draw once with simple texture.
    GLTexture tex = InitTextureWithSize(kSmallSize, expectedData.data());
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    ASSERT_GL_NO_ERROR();

    // Pack pixels tightly.
    glPixelStorei(GL_PACK_ALIGNMENT, 1);

    // Verify GetImage.
    std::vector<GLColor> actualData(kSmallSize * kSmallSize);
    glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, actualData.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(expectedData, actualData);
}

// Simple cube map test for GetTexImage
TEST_P(GetImageTest, CubeMap)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));

    const std::array<std::array<GLColor, kSmallSize * kSmallSize>, kCubeFaces.size()> expectedData =
        {{
            {GLColor::red, GLColor::red, GLColor::red, GLColor::red},
            {GLColor::green, GLColor::green, GLColor::green, GLColor::green},
            {GLColor::blue, GLColor::blue, GLColor::blue, GLColor::blue},
            {GLColor::yellow, GLColor::yellow, GLColor::yellow, GLColor::yellow},
            {GLColor::cyan, GLColor::cyan, GLColor::cyan, GLColor::cyan},
            {GLColor::magenta, GLColor::magenta, GLColor::magenta, GLColor::magenta},
        }};

    GLTexture texture;
    glBindTexture(GL_TEXTURE_CUBE_MAP, texture);

    for (size_t faceIndex = 0; faceIndex < kCubeFaces.size(); ++faceIndex)
    {
        glTexImage2D(kCubeFaces[faceIndex], 0, GL_RGBA, kSmallSize, kSmallSize, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, expectedData[faceIndex].data());
    }
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    // Pack pixels tightly.
    glPixelStorei(GL_PACK_ALIGNMENT, 1);

    // Verify GetImage.
    std::array<GLColor, kSmallSize *kSmallSize> actualData = {};
    for (size_t faceIndex = 0; faceIndex < kCubeFaces.size(); ++faceIndex)
    {
        glGetTexImageANGLE(kCubeFaces[faceIndex], 0, GL_RGBA, GL_UNSIGNED_BYTE, actualData.data());
        EXPECT_GL_NO_ERROR();
        EXPECT_EQ(expectedData[faceIndex], actualData);
    }
}

// Simple test for GetRenderbufferImage
TEST_P(GetImageTest, GetRenderbufferImage)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));

    std::vector<GLColor> expectedData = {GLColor::red, GLColor::blue, GLColor::green,
                                         GLColor::yellow};

    glViewport(0, 0, kSmallSize, kSmallSize);

    // Set up a simple Framebuffer with a Renderbuffer.
    GLRenderbuffer renderbuffer = InitRenderbufferWithSize(kSmallSize);
    GLFramebuffer framebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Draw once with simple texture.
    GLTexture tex = InitTextureWithSize(kSmallSize, expectedData.data());
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    ASSERT_GL_NO_ERROR();

    // Pack pixels tightly.
    glPixelStorei(GL_PACK_ALIGNMENT, 1);

    // Verify GetImage.
    std::vector<GLColor> actualData(kSmallSize * kSmallSize);
    glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, actualData.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(expectedData, actualData);
}

// Verifies that the extension enums and entry points are invalid when the extension is disabled.
TEST_P(GetImageTestNoExtensions, EntryPointsInactive)
{
    // Verify the extension is not enabled.
    ASSERT_FALSE(IsGLExtensionEnabled(kExtensionName));

    // Draw once with simple texture.
    GLTexture tex = InitSimpleTexture();
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    ASSERT_GL_NO_ERROR();

    // Query implementation format and type. Should give invalid enum.
    GLint param;
    glGetTexParameteriv(GL_TEXTURE_2D, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &param);
    EXPECT_GL_ERROR(GL_INVALID_ENUM);

    glGetTexParameteriv(GL_TEXTURE_2D, GL_IMPLEMENTATION_COLOR_READ_TYPE, &param);
    EXPECT_GL_ERROR(GL_INVALID_ENUM);

    // Verify calling GetTexImage produces an error.
    std::vector<GLColor> buffer(kSize * kSize, 0);
    glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    // Create a simple renderbuffer.
    GLRenderbuffer renderbuf = InitSimpleRenderbuffer();
    ASSERT_GL_NO_ERROR();

    // Query implementation format and type. Should give invalid enum.
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &param);
    EXPECT_GL_ERROR(GL_INVALID_ENUM);

    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &param);
    EXPECT_GL_ERROR(GL_INVALID_ENUM);

    // Verify calling GetRenderbufferImage produces an error.
    glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}

// Test LUMINANCE_ALPHA (non-renderable) format with GetTexImage
TEST_P(GetImageTest, GetTexImageLuminanceAlpha)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));

    constexpr GLColorRG kMediumLumAlpha = GLColorRG(kUNormHalf, kUNormHalf);
    std::vector<GLColorRG> expectedData = {kMediumLumAlpha, kMediumLumAlpha, kMediumLumAlpha,
                                           kMediumLumAlpha};

    glViewport(0, 0, kSmallSize, kSmallSize);

    // Set up a simple LUMINANCE_ALPHA texture
    GLTexture tex =
        InitTextureWithFormatAndSize(GL_LUMINANCE_ALPHA, kSmallSize, expectedData.data());

    // Draw once with simple texture.
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(kUNormHalf, kUNormHalf, kUNormHalf, kUNormHalf));
    ASSERT_GL_NO_ERROR();

    // Pack pixels tightly.
    glPixelStorei(GL_PACK_ALIGNMENT, 1);

    // Verify GetImage.
    std::vector<GLColorRG> actualData(kSmallSize * kSmallSize);
    glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, actualData.data());
    EXPECT_GL_NO_ERROR();
    for (uint32_t i = 0; i < kSmallSize * kSmallSize; ++i)
    {
        EXPECT_EQ(expectedData[i].R, actualData[i].R);
        EXPECT_EQ(expectedData[i].G, actualData[i].G);
    }
}

// Test LUMINANCE (non-renderable) format with GetTexImage
TEST_P(GetImageTest, GetTexImageLuminance)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));

    constexpr GLColorR kMediumLuminance = GLColorR(kUNormHalf);
    std::vector<GLColorR> expectedData  = {kMediumLuminance, kMediumLuminance, kMediumLuminance,
                                           kMediumLuminance};

    glViewport(0, 0, kSmallSize, kSmallSize);

    // Set up a simple LUMINANCE texture
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    GLTexture tex = InitTextureWithFormatAndSize(GL_LUMINANCE, kSmallSize, expectedData.data());

    // Draw once with simple texture.
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(kUNormHalf, kUNormHalf, kUNormHalf, kUNormFull));
    ASSERT_GL_NO_ERROR();

    // Pack pixels tightly.
    glPixelStorei(GL_PACK_ALIGNMENT, 1);

    // Verify GetImage.
    std::vector<GLColorR> actualData(kSmallSize * kSmallSize);
    glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, actualData.data());
    EXPECT_GL_NO_ERROR();
    for (uint32_t i = 0; i < kSmallSize * kSmallSize; ++i)
    {
        EXPECT_EQ(expectedData[i].R, actualData[i].R);
    }
}

// Test ALPHA (non-renderable) format with GetTexImage
TEST_P(GetImageTest, GetTexImageAlpha)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));

    constexpr GLColorR kMediumAlpha    = GLColorR(kUNormHalf);
    std::vector<GLColorR> expectedData = {kMediumAlpha, kMediumAlpha, kMediumAlpha, kMediumAlpha};

    glViewport(0, 0, kSmallSize, kSmallSize);

    // Set up a simple ALPHA texture
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    GLTexture tex = InitTextureWithFormatAndSize(GL_ALPHA, kSmallSize, expectedData.data());

    // Draw once with simple texture
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(kUNormZero, kUNormZero, kUNormZero, kUNormHalf));
    ASSERT_GL_NO_ERROR();

    // Pack pixels tightly.
    glPixelStorei(GL_PACK_ALIGNMENT, 1);

    // Verify we get back the correct pixels from GetTexImage
    std::vector<GLColorR> actualData(kSmallSize * kSmallSize);
    glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_ALPHA, GL_UNSIGNED_BYTE, actualData.data());
    EXPECT_GL_NO_ERROR();
    for (uint32_t i = 0; i < kSmallSize * kSmallSize; ++i)
    {
        EXPECT_EQ(expectedData[i].R, actualData[i].R);
    }
}

// Tests GetImage behaviour with an RGB image.
TEST_P(GetImageTest, GetImageRGB)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));

    std::vector<GLColorRGB> expectedData = {GLColorRGB::red, GLColorRGB::blue, GLColorRGB::green,
                                            GLColorRGB::yellow};

    glViewport(0, 0, kSmallSize, kSmallSize);

    // Pack pixels tightly.
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glPixelStorei(GL_PACK_ALIGNMENT, 1);

    // Init simple texture.
    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, kSmallSize, kSmallSize, 0, GL_RGB, GL_UNSIGNED_BYTE,
                 expectedData.data());
    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, kSmallSize / 2, kSmallSize / 2, 0, GL_RGB,
                 GL_UNSIGNED_BYTE, expectedData.data());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    // Verify GetImage.
    std::vector<GLColorRGB> actualData(kSmallSize * kSmallSize);
    glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, actualData.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(expectedData, actualData);

    // Draw after the GetImage.
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::yellow);
}

// Tests GetImage with 2D array textures.
TEST_P(GetImageTestES31, Texture2DArray)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));

    constexpr GLsizei kTextureSize = 2;
    constexpr GLsizei kLayers      = 4;

    std::vector<GLColor> expectedPixels = {
        GLColor::red,    GLColor::red,    GLColor::red,    GLColor::red,
        GLColor::green,  GLColor::green,  GLColor::green,  GLColor::green,
        GLColor::blue,   GLColor::blue,   GLColor::blue,   GLColor::blue,
        GLColor::yellow, GLColor::yellow, GLColor::yellow, GLColor::yellow,
    };

    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
    glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, kTextureSize, kTextureSize, kLayers, 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, expectedPixels.data());
    ASSERT_GL_NO_ERROR();

    std::vector<GLColor> actualPixels(expectedPixels.size(), GLColor::white);
    glGetTexImageANGLE(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, GL_UNSIGNED_BYTE, actualPixels.data());
    ASSERT_GL_NO_ERROR();
    EXPECT_EQ(expectedPixels, actualPixels);
}

// Tests GetImage with 3D textures.
TEST_P(GetImageTestES31, Texture3D)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));

    constexpr GLsizei kTextureSize = 2;

    std::vector<GLColor> expectedPixels = {
        GLColor::red,  GLColor::red,  GLColor::green,  GLColor::green,
        GLColor::blue, GLColor::blue, GLColor::yellow, GLColor::yellow,
    };

    GLTexture tex;
    glBindTexture(GL_TEXTURE_3D, tex);
    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, kTextureSize, kTextureSize, kTextureSize, 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, expectedPixels.data());
    ASSERT_GL_NO_ERROR();

    std::vector<GLColor> actualPixels(expectedPixels.size(), GLColor::white);
    glGetTexImageANGLE(GL_TEXTURE_3D, 0, GL_RGBA, GL_UNSIGNED_BYTE, actualPixels.data());
    ASSERT_GL_NO_ERROR();
    EXPECT_EQ(expectedPixels, actualPixels);
}

// Tests GetImage with cube map array textures.
TEST_P(GetImageTestES31, TextureCubeMapArray)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_cube_map_array") &&
                       !IsGLExtensionEnabled("GL_OES_texture_cube_map_array"));

    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));

    constexpr GLsizei kTextureSize = 1;
    constexpr GLsizei kLayers      = 2;

    std::vector<GLColor> expectedPixels = {
        GLColor::red,  GLColor::green,   GLColor::blue, GLColor::yellow,
        GLColor::cyan, GLColor::magenta, GLColor::red,  GLColor::green,
        GLColor::blue, GLColor::yellow,  GLColor::cyan, GLColor::magenta,
    };

    ASSERT_EQ(expectedPixels.size(),
              static_cast<size_t>(6 * kTextureSize * kTextureSize * kLayers));

    GLTexture tex;
    glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
    glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, kTextureSize, kTextureSize, kLayers * 6, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, expectedPixels.data());
    ASSERT_GL_NO_ERROR();

    std::vector<GLColor> actualPixels(expectedPixels.size(), GLColor::white);
    glGetTexImageANGLE(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                       actualPixels.data());
    ASSERT_GL_NO_ERROR();
    EXPECT_EQ(expectedPixels, actualPixels);
}

// Tests GetImage with an inconsistent 2D texture.
TEST_P(GetImageTest, InconsistentTexture2D)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));

    std::vector<GLColor> expectedData = {GLColor::red, GLColor::blue, GLColor::green,
                                         GLColor::yellow};

    glViewport(0, 0, kSmallSize, kSmallSize);

    // Draw once with simple texture.
    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSmallSize, kSmallSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 expectedData.data());
    // The texture becomes inconsistent because a second 2x2 image does not fit in the mip chain.
    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kSmallSize, kSmallSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 expectedData.data());

    // Pack pixels tightly.
    glPixelStorei(GL_PACK_ALIGNMENT, 1);

    // Verify GetImage.
    std::vector<GLColor> actualData(kSmallSize * kSmallSize, GLColor::white);
    glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, actualData.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(expectedData, actualData);

    std::fill(actualData.begin(), actualData.end(), GLColor::white);
    glGetTexImageANGLE(GL_TEXTURE_2D, 1, GL_RGBA, GL_UNSIGNED_BYTE, actualData.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(expectedData, actualData);
}

// Test GetImage with non-defined textures.
TEST_P(GetImageTest, EmptyTexture)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));

    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);

    std::vector<GLColor> expectedData(4, GLColor::white);
    std::vector<GLColor> actualData(4, GLColor::white);
    glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, actualData.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(expectedData, actualData);
}

struct CompressedFormat
{
    const GLenum id;

    // Texel/Block size in bytes
    const GLsizei size;

    // Texel/Block dimensions
    const GLsizei w;
    const GLsizei h;
};

struct CompressionExtension
{
    const char *name;
    const std::vector<CompressedFormat> formats;
    const bool supports2DArray;
    const bool supports3D;
};

// clang-format off
const CompressionExtension kCompressionExtensions[] = {
    // BC / DXT
    {"GL_EXT_texture_compression_dxt1",      {{GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, 4, 4},
                                              {GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8, 4, 4}},
                                             true, false},
    {"GL_ANGLE_texture_compression_dxt3",    {{GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 16, 4, 4}},
                                             true, false},
    {"GL_ANGLE_texture_compression_dxt5",    {{GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 16, 4, 4}},
                                             true, false},
    {"GL_EXT_texture_compression_s3tc_srgb", {{GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, 8, 4, 4},
                                              {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 8, 4, 4},
                                              {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 16, 4, 4},
                                              {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 16, 4, 4}},
                                             true, false},
    {"GL_EXT_texture_compression_rgtc",      {{GL_COMPRESSED_RED_RGTC1_EXT, 8, 4, 4},
                                              {GL_COMPRESSED_SIGNED_RED_RGTC1_EXT, 8, 4, 4},
                                              {GL_COMPRESSED_RED_GREEN_RGTC2_EXT, 16, 4, 4},
                                              {GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT, 16, 4, 4}},
                                             true, false},
    {"GL_EXT_texture_compression_bptc",      {{GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 16, 4, 4},
                                              {GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, 16, 4, 4},
                                              {GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, 16, 4, 4},
                                              {GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT, 16, 4, 4}},
                                             true, true},

    // ETC1
    {"GL_OES_compressed_ETC1_RGB8_texture",  {{GL_ETC1_RGB8_OES, 8, 4, 4}},
                                             false, false},

    // ETC2
    {"GL_ANGLE_compressed_texture_etc",      {{GL_COMPRESSED_R11_EAC, 8, 4, 4},
                                              {GL_COMPRESSED_SIGNED_R11_EAC, 8, 4, 4},
                                              {GL_COMPRESSED_RG11_EAC, 16, 4, 4},
                                              {GL_COMPRESSED_SIGNED_RG11_EAC, 16, 4, 4},
                                              {GL_COMPRESSED_RGB8_ETC2, 8, 4, 4},
                                              {GL_COMPRESSED_SRGB8_ETC2, 8, 4, 4},
                                              {GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 8, 4, 4},
                                              {GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 8, 4, 4},
                                              {GL_COMPRESSED_RGBA8_ETC2_EAC, 16, 4, 4},
                                              {GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, 16, 4, 4}},
                                             true, false},

    // ASTC
    {"GL_KHR_texture_compression_astc_ldr", {{GL_COMPRESSED_RGBA_ASTC_4x4_KHR, 16, 4, 4},
                                             {GL_COMPRESSED_RGBA_ASTC_5x4_KHR, 16, 5, 4},
                                             {GL_COMPRESSED_RGBA_ASTC_5x5_KHR, 16, 5, 5},
                                             {GL_COMPRESSED_RGBA_ASTC_6x5_KHR, 16, 6, 5},
                                             {GL_COMPRESSED_RGBA_ASTC_6x6_KHR, 16, 6, 6},
                                             {GL_COMPRESSED_RGBA_ASTC_8x5_KHR, 16, 8, 5},
                                             {GL_COMPRESSED_RGBA_ASTC_8x6_KHR, 16, 8, 6},
                                             {GL_COMPRESSED_RGBA_ASTC_8x8_KHR, 16, 8, 8},
                                             {GL_COMPRESSED_RGBA_ASTC_10x5_KHR, 16, 10, 5},
                                             {GL_COMPRESSED_RGBA_ASTC_10x6_KHR, 16, 10, 6},
                                             {GL_COMPRESSED_RGBA_ASTC_10x8_KHR, 16, 10, 8},
                                             {GL_COMPRESSED_RGBA_ASTC_10x10_KHR, 16, 10, 10},
                                             {GL_COMPRESSED_RGBA_ASTC_12x10_KHR, 16, 12, 10},
                                             {GL_COMPRESSED_RGBA_ASTC_12x12_KHR, 16, 12, 12},
                                             {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, 16, 4, 4},
                                             {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, 16, 5, 4},
                                             {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, 16, 5, 5},
                                             {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, 16, 6, 5},
                                             {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, 16, 6, 6},
                                             {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, 16, 8, 5},
                                             {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, 16, 8, 6},
                                             {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, 16, 8, 8},
                                             {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, 16, 10, 5},
                                             {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, 16, 10, 6},
                                             {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, 16, 10, 8},
                                             {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, 16, 10, 10},
                                             {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, 16, 12, 10},
                                             {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, 16, 12, 12}},
                                             true, true},
};
// clang-format on

// Basic GetCompressedTexImage.
TEST_P(GetImageTest, CompressedTexImage)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_compressed_ETC1_RGB8_texture"));

    constexpr GLsizei kRes       = 4;
    constexpr GLsizei kImageSize = 8;

    // This arbitrary 'compressed' data just has to be read back exactly as specified below.
    constexpr std::array<uint8_t, kImageSize> kExpectedData = {1, 2, 3, 4, 5, 6, 7, 8};

    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_ETC1_RGB8_OES, kRes, kRes, 0, kImageSize,
                           kExpectedData.data());

    if (IsFormatEmulated(GL_TEXTURE_2D))
    {
        INFO()
            << "Skipping emulated format GL_ETC1_RGB8_OES from GL_OES_compressed_ETC1_RGB8_texture";
        return;
    }

    std::array<uint8_t, kImageSize> actualData = {};
    glGetCompressedTexImageANGLE(GL_TEXTURE_2D, 0, actualData.data());
    ASSERT_GL_NO_ERROR();
    EXPECT_EQ(kExpectedData, actualData);
}

// Test validation for the compressed extension function.
TEST_P(GetImageTest, CompressedTexImageNegativeAPI)
{
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));

    // Verify the extension is enabled.
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_ANGLE_compressed_texture_etc"));

    constexpr GLsizei kRes       = 4;
    constexpr GLsizei kImageSize = 8;

    // This arbitrary 'compressed' data just has to be read back exactly as specified below.
    constexpr std::array<uint8_t, kImageSize> kExpectedData = {1, 2, 3, 4, 5, 6, 7, 8};

    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, kRes, kRes, 0, kImageSize,
                           kExpectedData.data());

    std::array<uint8_t, kImageSize> actualData = {};
    glGetCompressedTexImageANGLE(GL_TEXTURE_2D, 0, actualData.data());

    // Verify GetTexImage works with correct parameters or fails if format is emulated.
    if (IsFormatEmulated(GL_TEXTURE_2D))
    {
        EXPECT_GL_ERROR(GL_INVALID_OPERATION);
    }
    else
    {
        EXPECT_GL_NO_ERROR();
    }

    // Test invalid texture target.
    glGetCompressedTexImageANGLE(GL_TEXTURE_CUBE_MAP, 0, actualData.data());
    EXPECT_GL_ERROR(GL_INVALID_ENUM);

    // Test invalid texture level.
    glGetCompressedTexImageANGLE(GL_TEXTURE_2D, -1, actualData.data());
    EXPECT_GL_ERROR(GL_INVALID_VALUE);
    glGetCompressedTexImageANGLE(GL_TEXTURE_2D, 2000, actualData.data());
    EXPECT_GL_ERROR(GL_INVALID_VALUE);

    // Tests GetTexImage on a compressed texture.
    if (!IsFormatEmulated(GL_TEXTURE_2D))
    {
        glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE,
                           actualData.data());
        EXPECT_GL_ERROR(GL_INVALID_OPERATION);
    }
}

using TestFormatFunction =
    std::function<void(const CompressionExtension &, const CompressedFormat &)>;

void TestAllCompressedFormats(TestFormatFunction fun, int clientMajorVersion)
{
    for (CompressionExtension ext : kCompressionExtensions)
    {
        // ETC2/EAC formats are always supported on OpenGL ES 3.0+ but
        // the extension is only exposed if there is hardware support.
        const bool isETC2 =
            clientMajorVersion >= 3 &&
            ANGLE_UNSAFE_TODO(strcmp(ext.name, "GL_ANGLE_compressed_texture_etc")) == 0;
        if (!IsGLExtensionEnabled(ext.name) && !isETC2)
        {
            continue;
        }

        for (CompressedFormat format : ext.formats)
        {
            fun(ext, format);
        }
    }
}

// Test GetCompressedTexImage with all formats and
// and multiple resolution of the format's block size.
TEST_P(GetImageTest, CompressedTexImageAll)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));

    auto func = [](const CompressionExtension &ext, const CompressedFormat &format) {
        // Test with multiples of block size
        constexpr std::array<GLsizei, 2> multipliers = {1, 2};
        for (GLsizei multiplier : multipliers)
        {
            const GLsizei kImageSize = format.size * multiplier * multiplier;

            std::vector<uint8_t> expectedData;
            for (uint8_t i = 1; i < kImageSize + 1; i++)
            {
                expectedData.push_back(i);
            }

            GLTexture tex;
            glBindTexture(GL_TEXTURE_2D, tex);
            glCompressedTexImage2D(GL_TEXTURE_2D, 0, format.id, format.w * multiplier,
                                   format.h * multiplier, 0, kImageSize, expectedData.data());

            if (IsFormatEmulated(GL_TEXTURE_2D))
            {
                INFO() << "Skipping emulated format 0x" << std::hex << format.id << " from "
                       << ext.name;
                return;
            }

            std::vector<uint8_t> actualData(kImageSize);
            glGetCompressedTexImageANGLE(GL_TEXTURE_2D, 0, actualData.data());

            ASSERT_GL_NO_ERROR();
            EXPECT_EQ(expectedData, actualData);
        }
    };
    TestAllCompressedFormats(func, getClientMajorVersion());
}

// Test a resolution that is not a multiple of the block size with an ETC2 4x4 format.
TEST_P(GetImageTest, CompressedTexImageNotBlockMultiple)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_ANGLE_compressed_texture_etc"));

    constexpr GLsizei kRes       = 21;
    constexpr GLsizei kImageSize = 288;

    // This arbitrary 'compressed' data just has to be read back exactly as specified below.
    std::vector<uint8_t> expectedData;
    for (uint16_t j = 0; j < kImageSize; j++)
    {
        expectedData.push_back(j % std::numeric_limits<uint8_t>::max());
    }

    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, kRes, kRes, 0, kImageSize,
                           expectedData.data());

    if (IsFormatEmulated(GL_TEXTURE_2D))
    {
        INFO() << "Skipping emulated format GL_COMPRESSED_RGB8_ETC2";
        return;
    }

    std::vector<uint8_t> actualData(kImageSize);
    glGetCompressedTexImageANGLE(GL_TEXTURE_2D, 0, actualData.data());

    ASSERT_GL_NO_ERROR();
    EXPECT_EQ(expectedData, actualData);
}

void TestCompressedTexImage3D(GLenum target, uint32_t numLayers, int clientMajorVersion)
{
    auto func = [target, numLayers, clientMajorVersion](const CompressionExtension &ext,
                                                        const CompressedFormat &format) {
        // Skip extensions lacking 2D array and 3D support
        if ((target == GL_TEXTURE_2D_ARRAY && !ext.supports2DArray) ||
            (target == GL_TEXTURE_3D && !ext.supports3D))
        {
            return;
        }

        // GL_TEXTURE_3D with ASTC requires additional extension
        if (target == GL_TEXTURE_3D &&
            ANGLE_UNSAFE_TODO(strcmp(ext.name, "GL_KHR_texture_compression_astc_ldr")) == 0 &&
            !IsGLExtensionEnabled("GL_KHR_texture_compression_astc_sliced_3d") &&
            !IsGLExtensionEnabled("GL_KHR_texture_compression_astc_hdr"))
        {
            return;
        }

        const size_t size = format.size * numLayers;

        GLTexture texture;
        glBindTexture(target, texture);

        std::vector<uint8_t> expectedData;
        for (uint8_t i = 0; i < size; i++)
        {
            expectedData.push_back(i);
        }

        if (clientMajorVersion < 3)
        {
            ASSERT_TRUE(IsGLExtensionEnabled("GL_OES_texture_3D"));
            glCompressedTexImage3DOES(target, 0, format.id, format.w, format.h, numLayers, 0, size,
                                      expectedData.data());
        }
        else
        {
            glCompressedTexImage3D(target, 0, format.id, format.w, format.h, numLayers, 0, size,
                                   expectedData.data());
        }

        if (IsFormatEmulated(target))
        {
            INFO() << "Skipping emulated format 0x" << std::hex << format.id << " from "
                   << ext.name;
            return;
        }

        std::vector<uint8_t> actualData(size);
        glGetCompressedTexImageANGLE(target, 0, actualData.data());
        ASSERT_GL_NO_ERROR();
        EXPECT_EQ(expectedData, actualData);
    };
    TestAllCompressedFormats(func, clientMajorVersion);
}

// Tests GetCompressedTexImage with 2D array textures.
TEST_P(GetImageTestES3, CompressedTexImage2DArray)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
    TestCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, 8, getClientMajorVersion());
}

// Tests GetCompressedTexImage with 3D textures.
TEST_P(GetImageTest, CompressedTexImage3D)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_OES_texture_3D"));

    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
    TestCompressedTexImage3D(GL_TEXTURE_3D, 8, getClientMajorVersion());
}

// Simple cube map test for GetCompressedTexImage
TEST_P(GetImageTest, CompressedTexImageCubeMap)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));

    auto func = [](const CompressionExtension &ext, const CompressedFormat &format) {
        GLTexture texture;
        glBindTexture(GL_TEXTURE_CUBE_MAP, texture);

        std::vector<std::vector<uint8_t>> expectedData;
        for (uint32_t i = 0; i < kCubeFaces.size(); i++)
        {
            std::vector<uint8_t> face;
            for (uint8_t j = 0; j < format.size; j++)
            {
                face.push_back(static_cast<uint8_t>((i * format.size + j) %
                                                    std::numeric_limits<uint8_t>::max()));
            }
            expectedData.push_back(face);
        }

        for (size_t faceIndex = 0; faceIndex < kCubeFaces.size(); ++faceIndex)
        {
            glCompressedTexImage2D(kCubeFaces[faceIndex], 0, format.id, 4, 4, 0, format.size,
                                   expectedData[faceIndex].data());
        }

        if (IsFormatEmulated(GL_TEXTURE_CUBE_MAP))
        {
            INFO() << "Skipping emulated format 0x" << std::hex << format.id << " from "
                   << ext.name;
            return;
        }

        // Verify GetImage.
        for (size_t faceIndex = 0; faceIndex < kCubeFaces.size(); ++faceIndex)
        {
            std::vector<uint8_t> actualData(format.size);
            glGetCompressedTexImageANGLE(kCubeFaces[faceIndex], 0, actualData.data());
            EXPECT_GL_NO_ERROR();
            EXPECT_EQ(expectedData[faceIndex], actualData);
        }
    };
    TestAllCompressedFormats(func, getClientMajorVersion());
}

// Tests GetCompressedTexImage with cube map array textures.
TEST_P(GetImageTestES32, CompressedTexImageCubeMapArray)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));

    auto func = [](const CompressionExtension &ext, const CompressedFormat &format) {
        std::vector<uint8_t> expectedData;
        for (uint32_t i = 0; i < format.size * kCubeFaces.size(); i++)
        {
            expectedData.push_back(static_cast<uint8_t>(i % std::numeric_limits<uint8_t>::max()));
        }

        GLTexture tex;
        glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
        glCompressedTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, format.id, 4, 4, kCubeFaces.size(), 0,
                               expectedData.size() * sizeof(uint8_t), expectedData.data());
        ASSERT_GL_NO_ERROR();

        if (IsFormatEmulated(GL_TEXTURE_CUBE_MAP_ARRAY))
        {
            INFO() << "Skipping emulated format 0x" << std::hex << format.id << " from "
                   << ext.name;
            return;
        }

        // Verify GetImage.
        std::vector<uint8_t> actualData(format.size * kCubeFaces.size());
        glGetCompressedTexImageANGLE(GL_TEXTURE_CUBE_MAP_ARRAY, 0, actualData.data());
        EXPECT_GL_NO_ERROR();
        EXPECT_EQ(expectedData, actualData);
    };
    TestAllCompressedFormats(func, getClientMajorVersion());
}

// Tests GetCompressedTexImage with multiple mip levels.
TEST_P(GetImageTest, CompressedTexImageMultiLevel)
{
    // Verify the extension is enabled.
    ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));

    auto func = [](const CompressionExtension &ext, const CompressedFormat &format) {
        constexpr uint8_t kNumMipLevels = 8;
        GLTexture tex;
        glBindTexture(GL_TEXTURE_2D, tex);

        std::vector<std::vector<uint8_t>> expectedData;
        for (uint32_t mipLevel = 0; mipLevel < kNumMipLevels; mipLevel++)
        {
            uint32_t multiplier = static_cast<uint32_t>(pow(2, (kNumMipLevels - mipLevel) - 1));
            size_t levelSize    = format.size * multiplier * multiplier;

            std::vector<uint8_t> levelData;
            for (size_t j = 0; j < levelSize; j++)
            {
                levelData.push_back(static_cast<uint8_t>(j % std::numeric_limits<uint8_t>::max()));
            }
            expectedData.push_back(levelData);

            glCompressedTexImage2D(GL_TEXTURE_2D, mipLevel, format.id, format.w * multiplier,
                                   format.h * multiplier, 0, levelSize, levelData.data());
        }

        ASSERT_GL_NO_ERROR();

        if (IsFormatEmulated(GL_TEXTURE_2D))
        {
            INFO() << "Skipping emulated format 0x" << std::hex << format.id << " from "
                   << ext.name;
            return;
        }

        for (uint32_t mipLevel = 0; mipLevel < kNumMipLevels; mipLevel++)
        {
            uint32_t multiplier = static_cast<uint32_t>(pow(2, (kNumMipLevels - mipLevel) - 1));
            size_t levelSize    = format.size * multiplier * multiplier;

            std::vector<uint8_t> actualData(levelSize);
            glGetCompressedTexImageANGLE(GL_TEXTURE_2D, mipLevel, actualData.data());

            ASSERT_GL_NO_ERROR();
            EXPECT_EQ(expectedData[mipLevel], actualData);
        }
    };
    TestAllCompressedFormats(func, getClientMajorVersion());
}

struct PalettedFormat
{
    GLenum internalFormat;
    uint32_t indexBits;
    uint32_t redBlueBits;
    uint32_t greenBits;
    uint32_t alphaBits;
};

const PalettedFormat kPalettedFormats[] = {
    {GL_PALETTE4_RGB8_OES, 4, 8, 8, 0},     {GL_PALETTE4_RGBA8_OES, 4, 8, 8, 8},
    {GL_PALETTE4_R5_G6_B5_OES, 4, 5, 6, 0}, {GL_PALETTE4_RGBA4_OES, 4, 4, 4, 4},
    {GL_PALETTE4_RGB5_A1_OES, 4, 5, 5, 1},  {GL_PALETTE8_RGB8_OES, 8, 8, 8, 0},
    {GL_PALETTE8_RGBA8_OES, 8, 8, 8, 8},    {GL_PALETTE8_R5_G6_B5_OES, 8, 5, 6, 0},
    {GL_PALETTE8_RGBA4_OES, 8, 4, 4, 4},    {GL_PALETTE8_RGB5_A1_OES, 8, 5, 5, 1},
};

// Tests that glGetTexImageANGLE captures paletted format images in
// R8G8B8A8_UNORM and StoreRGBA8ToPalettedImpl compresses such images to the
// same paletted image.
TEST_P(GetImageTestES1, PalettedTexImage)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnable(GL_TEXTURE_2D);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    struct Vertex
    {
        GLfloat position[3];
        GLfloat uv[2];
    };

    std::vector<Vertex> vertices = {
        {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
        {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
        {{1.0f, -1.0f, 0.0f}, {1.0f, 0.0f}},
        {{1.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
    };
    glVertexPointer(3, GL_FLOAT, sizeof vertices[0], &vertices[0].position);
    glTexCoordPointer(2, GL_FLOAT, sizeof vertices[0], &vertices[0].uv);

    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    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);

    // Locations in the framebuffer where we will take the samples to compare

    const int width  = 16;
    const int height = width;

    for (PalettedFormat format : kPalettedFormats)
    {
        size_t paletteSizeInBytes =
            (1 << format.indexBits) *
            ((format.redBlueBits + format.greenBits + format.redBlueBits + format.alphaBits) / 8);
        size_t imageSize = paletteSizeInBytes + width * height * format.indexBits / 8;
        std::vector<uint8_t> testImage(imageSize);
        FillVectorWithRandomUBytes(&testImage);

        // Upload a random paletted image

        glCompressedTexImage2D(GL_TEXTURE_2D, 0, format.internalFormat, width, height, 0,
                               testImage.size(), testImage.data());
        EXPECT_GL_NO_ERROR();

        // Render a quad using this texture and capture the entire framebuffer contents

        glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size());
        EXPECT_GL_NO_ERROR();

        std::vector<GLColor> framebuffer(width * height);
        glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer.data());

        // Read it back as R8G8B8A8 UNORM

        std::vector<uint8_t> readback(width * height * 4);
        glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, readback.data());
        EXPECT_GL_NO_ERROR();

        // Recompress. This should produce the same, up to permutation of used
        // palette entries, image, as the one we uploaded. Upload it again.

        std::vector<uint8_t> recompressedImage(imageSize);
        angle::StoreRGBA8ToPalettedImpl(width, height, 1, format.indexBits, format.redBlueBits,
                                        format.greenBits, format.alphaBits, readback.data(),
                                        width * 4, width * height * 4, recompressedImage.data(),
                                        width * format.indexBits / 8,
                                        width * height * format.indexBits / 8);

        glCompressedTexImage2D(GL_TEXTURE_2D, 0, format.internalFormat, width, height, 0,
                               recompressedImage.size(), recompressedImage.data());
        EXPECT_GL_NO_ERROR();

        // Read the framebuffer again

        std::vector<GLColor> framebuffer2(width * height);
        glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer2.data());

        EXPECT_EQ(framebuffer, framebuffer2);
    }
}

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GetImageTest);
ANGLE_INSTANTIATE_TEST(GetImageTest,
                       ES2_VULKAN(),
                       ES3_VULKAN(),
                       ES2_VULKAN_SWIFTSHADER(),
                       ES3_VULKAN_SWIFTSHADER());

ANGLE_INSTANTIATE_TEST_ES1(GetImageTestES1);

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GetImageTestES3);
ANGLE_INSTANTIATE_TEST(GetImageTestES3, ES3_VULKAN(), ES3_VULKAN_SWIFTSHADER());

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GetImageTestES31);
ANGLE_INSTANTIATE_TEST(GetImageTestES31, ES31_VULKAN(), ES31_VULKAN_SWIFTSHADER());

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GetImageTestES32);
ANGLE_INSTANTIATE_TEST(GetImageTestES32, ES32_VULKAN(), ES32_VULKAN_SWIFTSHADER());

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GetImageTestNoExtensions);
ANGLE_INSTANTIATE_TEST(GetImageTestNoExtensions,
                       ES2_VULKAN(),
                       ES3_VULKAN(),
                       ES2_VULKAN_SWIFTSHADER(),
                       ES3_VULKAN_SWIFTSHADER());

}  // namespace
