//
// 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.
//
// ANGLETest:
//   Implementation of common ANGLE testing fixture.
//

#include "ANGLETest.h"
#include "common/unsafe_buffers.h"

#include <algorithm>
#include <cstdlib>

#include "common/PackedEnums.h"
#include "common/platform.h"
#include "gpu_info_util/SystemInfo.h"
#include "test_expectations/GPUTestConfig.h"
#include "util/EGLWindow.h"
#include "util/OSWindow.h"
#include "util/random_utils.h"
#include "util/test_utils.h"

#if defined(ANGLE_PLATFORM_WINDOWS)
#    include <VersionHelpers.h>
#endif  // defined(ANGLE_PLATFORM_WINDOWS)

#if defined(ANGLE_HAS_RAPIDJSON)
#    include "test_utils/runner/TestSuite.h"
#endif  // defined(ANGLE_HAS_RAPIDJSON)

namespace angle
{

const GLColorRGB GLColorRGB::black(0u, 0u, 0u);
const GLColorRGB GLColorRGB::blue(0u, 0u, 255u);
const GLColorRGB GLColorRGB::green(0u, 255u, 0u);
const GLColorRGB GLColorRGB::red(255u, 0u, 0u);
const GLColorRGB GLColorRGB::yellow(255u, 255u, 0u);
const GLColorRGB GLColorRGB::magenta(255u, 0u, 255u);
const GLColorRGB GLColorRGB::cyan(0u, 255u, 255u);
const GLColorRGB GLColorRGB::white(255u, 255u, 255u);

const GLColor GLColor::black            = GLColor(0u, 0u, 0u, 255u);
const GLColor GLColor::blue             = GLColor(0u, 0u, 255u, 255u);
const GLColor GLColor::cyan             = GLColor(0u, 255u, 255u, 255u);
const GLColor GLColor::green            = GLColor(0u, 255u, 0u, 255u);
const GLColor GLColor::red              = GLColor(255u, 0u, 0u, 255u);
const GLColor GLColor::transparentBlack = GLColor(0u, 0u, 0u, 0u);
const GLColor GLColor::white            = GLColor(255u, 255u, 255u, 255u);
const GLColor GLColor::yellow           = GLColor(255u, 255u, 0, 255u);
const GLColor GLColor::magenta          = GLColor(255u, 0u, 255u, 255u);

namespace
{
float ColorNorm(GLubyte channelValue)
{
    return static_cast<float>(channelValue) / 255.0f;
}

GLubyte ColorDenorm(float colorValue)
{
    return static_cast<GLubyte>(colorValue * 255.0f);
}

void TestPlatform_logError(PlatformMethods *platform, const char *errorMessage)
{
    auto *testPlatformContext = static_cast<TestPlatformContext *>(platform->context);
    if (testPlatformContext->ignoreMessages)
        return;

    GTEST_NONFATAL_FAILURE_(errorMessage);

    PrintStackBacktrace();
}

void TestPlatform_logWarning(PlatformMethods *platform, const char *warningMessage)
{
    auto *testPlatformContext = static_cast<TestPlatformContext *>(platform->context);
    if (testPlatformContext->ignoreMessages)
        return;

    if (testPlatformContext->warningsAsErrors)
    {
        FAIL() << warningMessage;
    }
    else
    {
#if !defined(ANGLE_TRACE_ENABLED) && !defined(ANGLE_ENABLE_ASSERTS)
        // LoggingAnnotator::logMessage() already logs via gl::Trace() under these defines:
        // https://crsrc.org/c/third_party/angle/src/common/debug.cpp;drc=d7d69375c25df2dc3980e6a4edc5d032ec940efc;l=62
        std::cerr << "Warning: " << warningMessage << std::endl;
#endif
    }
}

void TestPlatform_logInfo(PlatformMethods *platform, const char *infoMessage) {}

const std::array<Vector3, 6> kQuadVertices = {{
    Vector3(-1.0f, 1.0f, 0.5f),
    Vector3(-1.0f, -1.0f, 0.5f),
    Vector3(1.0f, -1.0f, 0.5f),
    Vector3(-1.0f, 1.0f, 0.5f),
    Vector3(1.0f, -1.0f, 0.5f),
    Vector3(1.0f, 1.0f, 0.5f),
}};

const std::array<Vector3, 4> kIndexedQuadVertices = {{
    Vector3(-1.0f, 1.0f, 0.5f),
    Vector3(-1.0f, -1.0f, 0.5f),
    Vector3(1.0f, -1.0f, 0.5f),
    Vector3(1.0f, 1.0f, 0.5f),
}};

constexpr std::array<GLushort, 6> kIndexedQuadIndices = {{0, 1, 2, 0, 2, 3}};

const char *GetColorName(GLColor color)
{
    if (color == GLColor::red)
    {
        return "Red";
    }

    if (color == GLColor::green)
    {
        return "Green";
    }

    if (color == GLColor::blue)
    {
        return "Blue";
    }

    if (color == GLColor::white)
    {
        return "White";
    }

    if (color == GLColor::black)
    {
        return "Black";
    }

    if (color == GLColor::transparentBlack)
    {
        return "Transparent Black";
    }

    if (color == GLColor::yellow)
    {
        return "Yellow";
    }

    if (color == GLColor::magenta)
    {
        return "Magenta";
    }

    if (color == GLColor::cyan)
    {
        return "Cyan";
    }

    return nullptr;
}

const char *GetColorName(GLColorRGB color)
{
    return GetColorName(GLColor(color.R, color.G, color.B, 255));
}

// Always re-use displays when using --bot-mode in the test runner.
bool gReuseDisplays = false;

bool ShouldAlwaysForceNewDisplay(const PlatformParameters &params)
{
    // When running WebGPU tests always force a new display.
    if (params.isWebGPU())
    {
        return true;
    }

    if (gReuseDisplays)
        return false;

    // We prefer to reuse config displays. This is faster and solves a driver issue where creating
    // many displays causes crashes. However this exposes other driver bugs on many other platforms.
    // Conservatively enable the feature only on Windows Intel and NVIDIA for now.
    SystemInfo *systemInfo = GetTestSystemInfo();
    return (!systemInfo || !IsWindows() || systemInfo->hasAMDGPU());
}

bool ShouldAlwaysForceNewWindow(const PlatformParameters &params)
{
    // The WebGPU underlying vulkan and D3D swap chain appears to fail to get a new image after
    // swapping when rapidly creating new swap chains for an existing window.
    if (params.isWebGPU())
    {
        return true;
    }

    return false;
}
}  // anonymous namespace

GPUTestConfig::API GetTestConfigAPIFromRenderer(angle::GLESDriverType driverType,
                                                EGLenum renderer,
                                                EGLenum deviceType)
{
    if (driverType != angle::GLESDriverType::AngleEGL &&
#if defined(ANGLE_TEST_ENABLE_SYSTEM_EGL)
        driverType != angle::GLESDriverType::SystemEGL &&
#endif
        driverType != angle::GLESDriverType::AngleVulkanSecondariesEGL)
    {
        return GPUTestConfig::kAPIUnknown;
    }

    switch (renderer)
    {
        case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
            return GPUTestConfig::kAPID3D11;
        case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
            return GPUTestConfig::kAPIGLDesktop;
        case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
            return GPUTestConfig::kAPIGLES;
        case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
            if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE)
            {
                return GPUTestConfig::kAPISwiftShader;
            }
            else
            {
                return GPUTestConfig::kAPIVulkan;
            }
        case EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE:
            return GPUTestConfig::kAPIMetal;
        case EGL_PLATFORM_ANGLE_TYPE_WEBGPU_ANGLE:
            return GPUTestConfig::kAPIWgpu;
        default:
            std::cerr << "Unknown Renderer enum: 0x" << std::hex << renderer << "\n";
            return GPUTestConfig::kAPIUnknown;
    }
}

GLColorRGB::GLColorRGB(const Vector3 &floatColor)
    : R(ColorDenorm(floatColor.x())), G(ColorDenorm(floatColor.y())), B(ColorDenorm(floatColor.z()))
{}

GLColor::GLColor(const Vector3 &floatColor)
    : R(ColorDenorm(floatColor.x())),
      G(ColorDenorm(floatColor.y())),
      B(ColorDenorm(floatColor.z())),
      A(255)
{}

GLColor::GLColor(const Vector4 &floatColor)
    : R(ColorDenorm(floatColor.x())),
      G(ColorDenorm(floatColor.y())),
      B(ColorDenorm(floatColor.z())),
      A(ColorDenorm(floatColor.w()))
{}

GLColor::GLColor(GLuint colorValue) : R(0), G(0), B(0), A(0)
{
    ANGLE_UNSAFE_TODO(memcpy(&R, &colorValue, sizeof(GLuint)));
}

GLuint GLColor::asUint() const
{
    GLuint uint = 0;
    ANGLE_UNSAFE_TODO(memcpy(&uint, &R, sizeof(GLuint)));
    return uint;
}

testing::AssertionResult GLColor::ExpectNear(const GLColor &expected, const GLColor &err) const
{
    testing::AssertionResult result(
        abs(int(expected.R) - this->R) <= err.R && abs(int(expected.G) - this->G) <= err.G &&
        abs(int(expected.B) - this->B) <= err.B && abs(int(expected.A) - this->A) <= err.A);
    if (!bool(result))
    {
        result << "Expected " << expected << "+/-" << err << ", was " << *this;
    }
    return result;
}

void CreatePixelCenterWindowCoords(const std::vector<Vector2> &pixelPoints,
                                   int windowWidth,
                                   int windowHeight,
                                   std::vector<Vector3> *outVertices)
{
    for (Vector2 pixelPoint : pixelPoints)
    {
        outVertices->emplace_back(Vector3((pixelPoint[0] + 0.5f) * 2.0f / windowWidth - 1.0f,
                                          (pixelPoint[1] + 0.5f) * 2.0f / windowHeight - 1.0f,
                                          0.0f));
    }
}

Vector4 GLColor::toNormalizedVector() const
{
    return Vector4(ColorNorm(R), ColorNorm(G), ColorNorm(B), ColorNorm(A));
}

GLColor RandomColor(angle::RNG *rng)
{
    return GLColor(rng->randomIntBetween(0, 255), rng->randomIntBetween(0, 255),
                   rng->randomIntBetween(0, 255), rng->randomIntBetween(0, 255));
}

GLColor ReadColor(GLint x, GLint y)
{
    GLColor actual;
    glReadPixels((x), (y), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &actual.R);
    EXPECT_GL_NO_ERROR();
    return actual;
}

bool operator==(const GLColor &a, const GLColor &b)
{
    return a.R == b.R && a.G == b.G && a.B == b.B && a.A == b.A;
}

bool operator!=(const GLColor &a, const GLColor &b)
{
    return !(a == b);
}

std::ostream &operator<<(std::ostream &ostream, const GLColor &color)
{
    const char *colorName = GetColorName(color);
    if (colorName)
    {
        return ostream << colorName;
    }

    ostream << "(" << static_cast<unsigned int>(color.R) << ", "
            << static_cast<unsigned int>(color.G) << ", " << static_cast<unsigned int>(color.B)
            << ", " << static_cast<unsigned int>(color.A) << ")";
    return ostream;
}

bool operator==(const GLColorRGB &a, const GLColorRGB &b)
{
    return a.R == b.R && a.G == b.G && a.B == b.B;
}

bool operator!=(const GLColorRGB &a, const GLColorRGB &b)
{
    return !(a == b);
}

std::ostream &operator<<(std::ostream &ostream, const GLColorRGB &color)
{
    const char *colorName = GetColorName(color);
    if (colorName)
    {
        return ostream << colorName;
    }

    ostream << "(" << static_cast<unsigned int>(color.R) << ", "
            << static_cast<unsigned int>(color.G) << ", " << static_cast<unsigned int>(color.B)
            << ")";
    return ostream;
}

std::ostream &operator<<(std::ostream &ostream, const GLColor32F &color)
{
    ostream << "(" << color.R << ", " << color.G << ", " << color.B << ", " << color.A << ")";
    return ostream;
}

GLColor32F ReadColor32F(GLint x, GLint y)
{
    GLColor32F actual;
    glReadPixels((x), (y), 1, 1, GL_RGBA, GL_FLOAT, &actual.R);
    EXPECT_GL_NO_ERROR();
    return actual;
}

void LoadEntryPointsWithUtilLoader(angle::GLESDriverType driverType)
{
#if defined(ANGLE_USE_UTIL_LOADER)
    Library *driverLibrary = ANGLETestEnvironment::GetDriverLibrary(driverType);
    if (driverLibrary == nullptr)
    {
        WriteDebugMessage("Failed to load library! (driverType = %d)",
                          static_cast<int>(driverType));
        return;
    }

    PFNEGLGETPROCADDRESSPROC getProcAddress;
    ANGLETestEnvironment::GetDriverLibrary(driverType)->getAs("eglGetProcAddress", &getProcAddress);
    ASSERT(nullptr != getProcAddress);

    LoadUtilEGL(getProcAddress);
    LoadUtilGLES(getProcAddress);
#endif  // defined(ANGLE_USE_UTIL_LOADER)
}

bool IsFormatEmulated(GLenum target)
{
    GLint readFormat;
    glGetTexParameteriv(target, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);

    // This helper only works for compressed formats
    return gl::IsEmulatedCompressedFormat(readFormat);
}

EGLenum GetEglPlatform()
{
    EGLenum eglPlatform = EGL_PLATFORM_ANGLE_ANGLE;

#if defined(ANGLE_TEST_ENABLE_SYSTEM_EGL)
    if (angle::IsAndroid())
    {
        eglPlatform = EGL_PLATFORM_ANDROID_KHR;
    }
#endif
    return eglPlatform;
}

EGLenum GetPbufferOnlyDefaultPlatformType()
{
    // Some tests only need a pbuffer.  On Wayland, EGL configs don't advertise pbuffers, so default
    // to X11 if enabled so the tests can run.  The value returned by this function should be passed
    // as the EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE attribute.
#if defined(ANGLE_USE_X11)
    return EGL_PLATFORM_X11_EXT;
#else
    // Using 0 means the default is chosen.
    return 0;
#endif
}
}  // namespace angle

using namespace angle;

PlatformMethods gDefaultPlatformMethods;

namespace
{
TestPlatformContext gPlatformContext;

// After a fixed number of iterations we reset the test window. This works around some driver bugs.
constexpr uint32_t kWindowReuseLimit = 50;

constexpr char kUseConfig[]                      = "--use-config=";
constexpr char kReuseDisplays[]                  = "--reuse-displays";
constexpr char kEnableANGLEPerTestCaptureLabel[] = "--angle-per-test-capture-label";
constexpr char kBatchId[]                        = "--batch-id=";
constexpr char kDelayTestStart[]                 = "--delay-test-start=";
constexpr char kRenderDoc[]                      = "--renderdoc";
constexpr char kNoRenderDoc[]                    = "--no-renderdoc";

void SetupEnvironmentVarsForCaptureReplay()
{
    const ::testing::TestInfo *const testInfo =
        ::testing::UnitTest::GetInstance()->current_test_info();
    std::string testName = std::string{testInfo->name()};
    std::replace(testName.begin(), testName.end(), '/', '_');
    SetEnvironmentVar("ANGLE_CAPTURE_LABEL",
                      (std::string{testInfo->test_suite_name()} + "_" + testName).c_str());
}
}  // anonymous namespace

int gTestStartDelaySeconds = 0;

int GetTestStartDelaySeconds()
{
    return gTestStartDelaySeconds;
}

void SetTestStartDelay(const char *testStartDelay)
{
    gTestStartDelaySeconds = std::stoi(testStartDelay);
}

// static
std::array<Vector3, 6> ANGLETestBase::GetQuadVertices()
{
    return kQuadVertices;
}

// static
std::array<GLushort, 6> ANGLETestBase::GetQuadIndices()
{
    return kIndexedQuadIndices;
}

// static
std::array<Vector3, 4> ANGLETestBase::GetIndexedQuadVertices()
{
    return kIndexedQuadVertices;
}

testing::AssertionResult AssertEGLEnumsEqual(const char *lhsExpr,
                                             const char *rhsExpr,
                                             EGLenum lhs,
                                             EGLenum rhs)
{
    if (lhs == rhs)
    {
        return testing::AssertionSuccess();
    }
    else
    {
        std::stringstream strstr;
        strstr << std::hex << lhsExpr << " (0x" << int(lhs) << ") != " << rhsExpr << " (0x"
               << int(rhs) << ")";
        return testing::AssertionFailure() << strstr.str();
    }
}

void *ANGLETestBase::operator new(size_t size)
{
    void *ptr = malloc(size ? size : size + 1);
    // Initialize integer primitives to large positive values to avoid tests relying
    // on the assumption that primitives (e.g. GLuint) would be zero-initialized.
    ANGLE_UNSAFE_TODO(memset(ptr, 0x7f, size));
    return ptr;
}

void ANGLETestBase::operator delete(void *ptr)
{
    free(ptr);
}

ANGLETestBase::ANGLETestBase(const PlatformParameters &params)
    : mWidth(16),
      mHeight(16),
      mIgnoreD3D11SDKLayersWarnings(false),
      mQuadVertexBuffer(0),
      mQuadIndexBuffer(0),
      m2DTexturedQuadProgram(0),
      m3DTexturedQuadProgram(0),
      m2DArrayTexturedQuadProgram(0),
      mDeferContextInit(false),
      mAlwaysForceNewDisplay(ShouldAlwaysForceNewDisplay(params)),
      mForceNewDisplay(mAlwaysForceNewDisplay),
      mSetUpCalled(false),
      mTearDownCalled(false),
      mCurrentParams(nullptr),
      mFixture(nullptr)
{
    // Override the default platform methods with the ANGLE test methods pointer.
    PlatformParameters withMethods            = params;
    withMethods.eglParameters.platformMethods = &gDefaultPlatformMethods;

    if (withMethods.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
    {
#if defined(ANGLE_ENABLE_VULKAN_VALIDATION_LAYERS)
        withMethods.eglParameters.debugLayersEnabled = true;
#else
        withMethods.eglParameters.debugLayersEnabled = false;
#endif
    }

    if (gEnableRenderDocCapture)
    {
        mRenderDoc.attach();
    }

    auto iter = gFixtures.find(withMethods);
    if (iter != gFixtures.end())
    {
        mCurrentParams = &iter->first;

        if (!params.noFixture)
        {
            mFixture = &iter->second;
            mFixture->configParams.reset();
        }
        return;
    }

    TestFixture platform;
    auto insertIter = gFixtures.emplace(withMethods, platform);
    mCurrentParams  = &insertIter.first->first;

    if (!params.noFixture)
    {
        mFixture = &insertIter.first->second;
        initOSWindow();
    }
}

void ANGLETestBase::initOSWindow()
{
    std::stringstream windowNameStream;
    windowNameStream << "ANGLE Tests - " << *mCurrentParams;
    std::string windowName = windowNameStream.str();

    if (IsAndroid())
    {
        // Only one window per test application on Android, shared among all fixtures
        mFixture->osWindow = mOSWindowSingleton;
    }

    if (mFixture->osWindow == nullptr)
    {
        mFixture->osWindow = OSWindow::New();
        if (mFixture->osWindow == nullptr)
        {
            FATAL() << "Failed to create a new window";
        }
        mFixture->osWindow->disableErrorMessageDialog();
        if (!mFixture->osWindow->initialize(windowName, 128, 128))
        {
            std::cerr << "Failed to initialize OS Window.\n";
        }

        if (IsAndroid())
        {
            // Initialize the single window on Andoird only once
            mOSWindowSingleton = mFixture->osWindow;
        }
    }

    if (!mFixture->osWindow->valid())
    {
        return;
    }

    // On Linux we must keep the test windows visible. On Windows it doesn't seem to need it.
    setWindowVisible(getOSWindow(), !IsWindows());

    switch (mCurrentParams->driver)
    {
        case GLESDriverType::AngleEGL:
        case GLESDriverType::AngleVulkanSecondariesEGL:
        case GLESDriverType::SystemEGL:
        case GLESDriverType::ZinkEGL:
        {
            mFixture->eglWindow =
                EGLWindow::New(mCurrentParams->majorVersion, mCurrentParams->minorVersion);
            break;
        }

        case GLESDriverType::SystemWGL:
        {
            // WGL tests are currently disabled.
            std::cerr << "Unsupported driver." << std::endl;
            break;
        }
    }
}

ANGLETestBase::~ANGLETestBase()
{
    if (mQuadVertexBuffer)
    {
        glDeleteBuffers(1, &mQuadVertexBuffer);
    }
    if (mQuadIndexBuffer)
    {
        glDeleteBuffers(1, &mQuadIndexBuffer);
    }
    if (m2DTexturedQuadProgram)
    {
        glDeleteProgram(m2DTexturedQuadProgram);
    }
    if (m3DTexturedQuadProgram)
    {
        glDeleteProgram(m3DTexturedQuadProgram);
    }
    if (m2DArrayTexturedQuadProgram)
    {
        glDeleteProgram(m2DArrayTexturedQuadProgram);
    }

    if (!mSetUpCalled)
    {
        GTEST_NONFATAL_FAILURE_("SetUp not called.");
    }

    if (!mTearDownCalled)
    {
        GTEST_NONFATAL_FAILURE_("TearDown not called.");
    }
}

void ANGLETestBase::ANGLETestSetUp()
{
    mSetUpCalled = true;

    // Delay test startup to allow a debugger to attach.
    if (GetTestStartDelaySeconds())
    {
        angle::Sleep(GetTestStartDelaySeconds() * 1000);
    }

    gDefaultPlatformMethods.logError   = TestPlatform_logError;
    gDefaultPlatformMethods.logWarning = TestPlatform_logWarning;
    gDefaultPlatformMethods.logInfo    = TestPlatform_logInfo;
    gDefaultPlatformMethods.context    = &gPlatformContext;

    gPlatformContext.ignoreMessages   = false;
    gPlatformContext.warningsAsErrors = false;
    gPlatformContext.currentTest      = this;

    const testing::TestInfo *testInfo = testing::UnitTest::GetInstance()->current_test_info();

    // Check the skip list.

    angle::GPUTestConfig::API api = GetTestConfigAPIFromRenderer(
        mCurrentParams->driver, mCurrentParams->getRenderer(), mCurrentParams->getDeviceType());
    GPUTestConfig testConfig = GPUTestConfig(api, 0);

    std::stringstream fullTestNameStr;
    fullTestNameStr << testInfo->test_suite_name() << "." << testInfo->name();
    std::string fullTestName = fullTestNameStr.str();

    // TODO(b/279980674): TestSuite depends on rapidjson which we don't have in aosp builds,
    // for now disable both TestSuite and expectations.
#if defined(ANGLE_HAS_RAPIDJSON)
    TestSuite *testSuite = TestSuite::GetInstance();
    int32_t testExpectation =
        testSuite->getTestExpectationWithConfigAndUpdateTimeout(testConfig, fullTestName);

    if (testExpectation == GPUTestExpectationsParser::kGpuTestSkip)
    {
        GTEST_SKIP() << "Test skipped on this config";
    }
#endif

    if (IsWindows())
    {
        WriteDebugMessage("Entering %s\n", fullTestName.c_str());
    }

    if (mCurrentParams->noFixture)
    {
        LoadEntryPointsWithUtilLoader(mCurrentParams->driver);
        mIsSetUp = true;
        return;
    }

    if (!mLastLoadedDriver.valid() || mCurrentParams->driver != mLastLoadedDriver.value())
    {
        LoadEntryPointsWithUtilLoader(mCurrentParams->driver);
        mLastLoadedDriver = mCurrentParams->driver;
    }

    if (gEnableANGLEPerTestCaptureLabel)
    {
        SetupEnvironmentVarsForCaptureReplay();
    }

    if (ShouldAlwaysForceNewWindow(*mCurrentParams))
    {
        OSWindow::Delete(&mFixture->osWindow);
        initOSWindow();
    }

    if (!mFixture->osWindow->valid())
    {
        mIsSetUp = true;
        return;
    }

    // WGL tests are currently disabled.
    if (mFixture->wglWindow)
    {
        FAIL() << "Unsupported driver.";
    }

    // Resize the window before creating the context so that the first make current
    // sets the viewport and scissor box to the right size.
    bool needSwap = false;

    int osWindowWidth  = mFixture->osWindow->getWidth();
    int osWindowHeight = mFixture->osWindow->getHeight();

    const bool isRotated = mCurrentParams->isEnableRequested(Feature::EmulatedPrerotation90) ||
                           mCurrentParams->isEnableRequested(Feature::EmulatedPrerotation270);
    if (isRotated)
    {
        std::swap(osWindowWidth, osWindowHeight);
    }

    if (osWindowWidth != mWidth || osWindowHeight != mHeight)
    {
        int newWindowWidth  = mWidth;
        int newWindowHeight = mHeight;
        if (isRotated)
        {
            std::swap(newWindowWidth, newWindowHeight);
        }

        if (!mFixture->osWindow->resize(newWindowWidth, newWindowHeight))
        {
            FAIL() << "Failed to resize ANGLE test window.";
        }
        needSwap = true;
    }

    Library *driverLib = ANGLETestEnvironment::GetDriverLibrary(mCurrentParams->driver);

    // Overriding ANGLE features requires the extension EGL_ANGLE_feature_control.
    // Only allow skipping tests due to unsupported ANGLE extensions when testing the system EGL,
    // since we want it to be obvious if ANGLE itself stops exposing them.
    // Must be checked before initializing the Display, since
    if (isDriverSystemEgl())
    {
        if ((!mCurrentParams->eglParameters.enabledFeatureOverrides.empty() ||
             !mCurrentParams->eglParameters.disabledFeatureOverrides.empty()) &&
            !IsEGLClientExtensionEnabled("EGL_ANGLE_feature_control"))
        {
            GTEST_SKIP() << "Test skipped because EGL_ANGLE_feature_control is not available.";
        }
    }

    if (mForceNewDisplay || !mFixture->eglWindow->isDisplayInitialized())
    {
        mFixture->eglWindow->destroyGL();
        if (!mFixture->eglWindow->initializeDisplay(mFixture->osWindow, driverLib,
                                                    mCurrentParams->driver,
                                                    mCurrentParams->eglParameters))
        {
            FAIL() << "EGL Display init failed.";
        }
    }
    else if (mCurrentParams->eglParameters != mFixture->eglWindow->getPlatform())
    {
        FAIL() << "Internal parameter conflict error.";
    }

    // Skip tests that require unsupported ANGLE extensions.
    checkUnsupportedExtensions();
    if (IsSkipped())
    {
        return;
    }

    const GLWindowResult windowResult = mFixture->eglWindow->initializeSurface(
        mFixture->osWindow, driverLib, mFixture->configParams);

    if (windowResult != GLWindowResult::NoError)
    {
        if (windowResult != GLWindowResult::Error)
        {
            // If the test requests an extension that isn't supported, automatically skip the
            // test.
            GTEST_SKIP() << "Test skipped due to missing extension";
        }
        else if (mFixture->configParams.multisample)
        {
            // If the test requests a multisampled window that isn't supported, automatically
            // skip the test.
            GTEST_SKIP() << "Test skipped due to no multisampled configs available";
        }
        else
        {
            // Otherwise fail the test.
            FAIL() << "egl surface init failed.";
        }
    }

    if (!mDeferContextInit && !mFixture->eglWindow->initializeContext())
    {
        FAIL() << "GL Context init failed.";
    }

    if (mFixture->eglWindow->getClientMajorVersion() != mCurrentParams->majorVersion ||
        mFixture->eglWindow->getClientMinorVersion() != mCurrentParams->minorVersion)
    {
        WARN() << "Requested Context version does not match the version created. Requested: "
               << mCurrentParams->majorVersion << "." << mCurrentParams->minorVersion
               << ", Actual: " << mFixture->eglWindow->getClientMajorVersion() << "."
               << mFixture->eglWindow->getClientMinorVersion();
    }

    if (needSwap)
    {
        // Swap the buffers so that the default framebuffer picks up the resize
        // which will allow follow-up test code to assume the framebuffer covers
        // the whole window.
        swapBuffers();
    }

    // This Viewport command is not strictly necessary but we add it so that programs
    // taking OpenGL traces can guess the size of the default framebuffer and show it
    // in their UIs
    glViewport(0, 0, mWidth, mHeight);

    mIsSetUp = true;

    mRenderDoc.startFrame();
}

void ANGLETestBase::checkUnsupportedExtensions()
{
    // Only allow skipping tests due to unsupported ANGLE extensions when testing the system EGL,
    // since we want it to be obvious if ANGLE itself stops exposing them.
    if (mCurrentParams->driver != GLESDriverType::SystemEGL)
    {
        return;
    }

    if ((mFixture->configParams.webGLCompatibility || mFixture->configParams.hardenedContext) &&
        !IsEGLDisplayExtensionEnabled(mFixture->eglWindow->getDisplay(),
                                      "EGL_ANGLE_create_context_webgl_compatibility"))
    {
        GTEST_SKIP()
            << "Test skipped due to EGL_ANGLE_create_context_webgl_compatibility not available";
    }
    if (mFixture->configParams.robustResourceInit &&
        !IsEGLDisplayExtensionEnabled(mFixture->eglWindow->getDisplay(),
                                      "EGL_ANGLE_robust_resource_initialization"))
    {
        GTEST_SKIP()
            << "Test skipped due to EGL_ANGLE_robust_resource_initialization not available";
    }
    if (!mFixture->configParams.extensionsEnabled &&
        !IsEGLDisplayExtensionEnabled(mFixture->eglWindow->getDisplay(),
                                      "EGL_ANGLE_create_context_extensions_enabled"))
    {
        GTEST_SKIP()
            << "Test skipped due to EGL_ANGLE_create_context_extensions_enabled not available";
    }
    if (!mFixture->configParams.bindGeneratesResource &&
        !IsEGLDisplayExtensionEnabled(mFixture->eglWindow->getDisplay(),
                                      "EGL_CHROMIUM_create_context_bind_generates_resource"))
    {
        GTEST_SKIP() << "Test skipped due to "
                        "EGL_CHROMIUM_create_context_bind_generates_resource not available";
    }
    if (!mFixture->configParams.clientArraysEnabled &&
        !IsEGLDisplayExtensionEnabled(mFixture->eglWindow->getDisplay(),
                                      "EGL_ANGLE_create_context_client_arrays"))
    {
        GTEST_SKIP() << "Test skipped due to EGL_ANGLE_create_context_client_arrays not available";
    }
    if (!mFixture->configParams.contextProgramCacheEnabled &&
        !IsEGLDisplayExtensionEnabled(mFixture->eglWindow->getDisplay(),
                                      "EGL_ANGLE_program_cache_control"))
    {
        GTEST_SKIP() << "Test skipped due to EGL_ANGLE_program_cache_control not available";
    }
}

void ANGLETestBase::ANGLETestPreTearDown()
{
    // We swap an extra time before we call "tearDown" to capture resources before they're freed.
    if (gEnableANGLEPerTestCaptureLabel)
    {
        swapBuffers();
    }
}

void ANGLETestBase::ANGLETestTearDown()
{
    mTearDownCalled              = true;
    gPlatformContext.currentTest = nullptr;

    if (IsWindows())
    {
        const testing::TestInfo *info = testing::UnitTest::GetInstance()->current_test_info();
        WriteDebugMessage("Exiting %s.%s\n", info->test_suite_name(), info->name());
    }

    if (mCurrentParams->noFixture || !mFixture->osWindow || !mFixture->osWindow->valid())
    {
        mRenderDoc.endFrame();
        return;
    }

    swapBuffers();
    mFixture->osWindow->messageLoop();

    mRenderDoc.endFrame();

    if (mFixture->eglWindow)
    {
        checkD3D11SDKLayersMessages();
    }

    if (mFixture->reuseCounter++ >= kWindowReuseLimit || mForceNewDisplay)
    {
        if (!mForceNewDisplay)
        {
            printf("Recreating test window because of reuse limit of %d\n", kWindowReuseLimit);
        }

        mFixture->reuseCounter = 0;
        getGLWindow()->destroyGL();
    }
    else
    {
        mFixture->eglWindow->destroyContext();
        mFixture->eglWindow->destroySurface();
    }

    Event myEvent;
    while (mFixture->osWindow && mFixture->osWindow->popEvent(&myEvent))
    {
        if (myEvent.Type == Event::EVENT_CLOSED)
        {
            exit(0);
        }
    }

    if (ShouldAlwaysForceNewWindow(*mCurrentParams))
    {
        OSWindow::Delete(&mFixture->osWindow);
    }
}

void ANGLETestBase::ReleaseFixtures()
{
    for (auto it = gFixtures.begin(); it != gFixtures.end(); it++)
    {
        TestFixture &fixture = it->second;
        if (fixture.eglWindow != nullptr)
        {
            fixture.eglWindow->destroyGL();
            EGLWindow::Delete(&fixture.eglWindow);
        }

        if (IsAndroid())
        {
            if (mOSWindowSingleton != nullptr)
            {
                OSWindow::Delete(&mOSWindowSingleton);
            }
            fixture.osWindow = nullptr;
        }
        else
        {
            if (fixture.osWindow != nullptr)
            {
                OSWindow::Delete(&fixture.osWindow);
            }
        }
    }

    gFixtures.clear();
}

void ANGLETestBase::swapBuffers()
{
    if (getGLWindow()->isGLInitialized())
    {
        getGLWindow()->swap();

        if (mFixture->eglWindow)
        {
            EXPECT_EGL_SUCCESS();
        }
    }
}

void ANGLETestBase::setupQuadVertexBuffer(GLfloat positionAttribZ, GLfloat positionAttribXYScale)
{
    if (mQuadVertexBuffer == 0)
    {
        glGenBuffers(1, &mQuadVertexBuffer);
    }

    auto quadVertices = GetQuadVertices();
    for (Vector3 &vertex : quadVertices)
    {
        vertex.x() *= positionAttribXYScale;
        vertex.y() *= positionAttribXYScale;
        vertex.z() = positionAttribZ;
    }

    glBindBuffer(GL_ARRAY_BUFFER, mQuadVertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 6, quadVertices.data(), GL_STATIC_DRAW);
}

void ANGLETestBase::setupIndexedQuadVertexBuffer(GLfloat positionAttribZ,
                                                 GLfloat positionAttribXYScale)
{
    if (mQuadVertexBuffer == 0)
    {
        glGenBuffers(1, &mQuadVertexBuffer);
    }

    auto quadVertices = kIndexedQuadVertices;
    for (Vector3 &vertex : quadVertices)
    {
        vertex.x() *= positionAttribXYScale;
        vertex.y() *= positionAttribXYScale;
        vertex.z() = positionAttribZ;
    }

    glBindBuffer(GL_ARRAY_BUFFER, mQuadVertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 4, quadVertices.data(), GL_STATIC_DRAW);
}

void ANGLETestBase::setupIndexedQuadIndexBuffer()
{
    if (mQuadIndexBuffer == 0)
    {
        glGenBuffers(1, &mQuadIndexBuffer);
    }

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mQuadIndexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(kIndexedQuadIndices), kIndexedQuadIndices.data(),
                 GL_STATIC_DRAW);
}

// static
void ANGLETestBase::drawQuad(GLuint program,
                             const std::string &positionAttribName,
                             GLfloat positionAttribZ)
{
    drawQuad(program, positionAttribName, positionAttribZ, 1.0f);
}

// static
void ANGLETestBase::drawQuad(GLuint program,
                             const std::string &positionAttribName,
                             GLfloat positionAttribZ,
                             GLfloat positionAttribXYScale)
{
    drawQuad(program, positionAttribName, positionAttribZ, positionAttribXYScale, false);
}

void ANGLETestBase::drawQuad(GLuint program,
                             const std::string &positionAttribName,
                             GLfloat positionAttribZ,
                             GLfloat positionAttribXYScale,
                             bool useVertexBuffer)
{
    drawQuad(program, positionAttribName, positionAttribZ, positionAttribXYScale, useVertexBuffer,
             false, false, 0u);
}

void ANGLETestBase::drawQuadInstanced(GLuint program,
                                      const std::string &positionAttribName,
                                      GLfloat positionAttribZ,
                                      GLfloat positionAttribXYScale,
                                      bool useVertexBuffer,
                                      GLuint numInstances)
{
    drawQuad(program, positionAttribName, positionAttribZ, positionAttribXYScale, useVertexBuffer,
             true, false, numInstances);
}

void ANGLETestBase::drawPatches(GLuint program,
                                const std::string &positionAttribName,
                                GLfloat positionAttribZ,
                                GLfloat positionAttribXYScale,
                                bool useVertexBuffer)
{
    drawQuad(program, positionAttribName, positionAttribZ, positionAttribXYScale, useVertexBuffer,
             false, true, 0u);
}

void ANGLETestBase::drawQuad(GLuint program,
                             const std::string &positionAttribName,
                             GLfloat positionAttribZ,
                             GLfloat positionAttribXYScale,
                             bool useVertexBuffer,
                             bool useInstancedDrawCalls,
                             bool useTessellationPatches,
                             GLuint numInstances)
{
    GLint previousProgram = 0;
    glGetIntegerv(GL_CURRENT_PROGRAM, &previousProgram);
    if (previousProgram != static_cast<GLint>(program))
    {
        glUseProgram(program);
    }

    GLint previousBuffer = 0;
    glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &previousBuffer);

    GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());

    std::array<Vector3, 6> quadVertices = GetQuadVertices();

    if (useVertexBuffer)
    {
        setupQuadVertexBuffer(positionAttribZ, positionAttribXYScale);
        glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
        glBindBuffer(GL_ARRAY_BUFFER, previousBuffer);
    }
    else
    {
        for (Vector3 &vertex : quadVertices)
        {
            vertex.x() *= positionAttribXYScale;
            vertex.y() *= positionAttribXYScale;
            vertex.z() = positionAttribZ;
        }

        if (previousBuffer != 0)
        {
            glBindBuffer(GL_ARRAY_BUFFER, 0);
        }
        glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, quadVertices.data());
        if (previousBuffer != 0)
        {
            glBindBuffer(GL_ARRAY_BUFFER, previousBuffer);
        }
    }
    glEnableVertexAttribArray(positionLocation);
    GLenum drawMode = (useTessellationPatches) ? GL_PATCHES : GL_TRIANGLES;

    if (useInstancedDrawCalls)
    {
        glDrawArraysInstanced(drawMode, 0, 6, numInstances);
    }
    else
    {
        glDrawArrays(drawMode, 0, 6);
    }

    glDisableVertexAttribArray(positionLocation);
    glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, nullptr);

    if (previousProgram != static_cast<GLint>(program))
    {
        glUseProgram(previousProgram);
    }
}

void ANGLETestBase::drawQuadPPO(GLuint vertProgram,
                                const std::string &positionAttribName,
                                const GLfloat positionAttribZ,
                                const GLfloat positionAttribXYScale)
{
    GLint activeProgram = 0;
    glGetIntegerv(GL_CURRENT_PROGRAM, &activeProgram);
    if (activeProgram)
    {
        glUseProgram(0);
    }

    std::array<Vector3, 6> quadVertices = GetQuadVertices();

    for (Vector3 &vertex : quadVertices)
    {
        vertex.x() *= positionAttribXYScale;
        vertex.y() *= positionAttribXYScale;
        vertex.z() = positionAttribZ;
    }

    GLint positionLocation = glGetAttribLocation(vertProgram, positionAttribName.c_str());

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, quadVertices.data());
    glEnableVertexAttribArray(positionLocation);

    glDrawArrays(GL_TRIANGLES, 0, 6);

    glDisableVertexAttribArray(positionLocation);
    glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, nullptr);

    if (activeProgram)
    {
        glUseProgram(static_cast<GLuint>(activeProgram));
    }
}

void ANGLETestBase::drawIndexedQuad(GLuint program,
                                    const std::string &positionAttribName,
                                    GLfloat positionAttribZ)
{
    drawIndexedQuad(program, positionAttribName, positionAttribZ, 1.0f);
}

void ANGLETestBase::drawIndexedQuad(GLuint program,
                                    const std::string &positionAttribName,
                                    GLfloat positionAttribZ,
                                    GLfloat positionAttribXYScale)
{
    ASSERT(!mFixture || !mFixture->configParams.webGLCompatibility);
    drawIndexedQuad(program, positionAttribName, positionAttribZ, positionAttribXYScale, false);
}

void ANGLETestBase::drawIndexedQuad(GLuint program,
                                    const std::string &positionAttribName,
                                    GLfloat positionAttribZ,
                                    GLfloat positionAttribXYScale,
                                    bool useIndexBuffer)
{
    drawIndexedQuad(program, positionAttribName, positionAttribZ, positionAttribXYScale,
                    useIndexBuffer, false);
}

void ANGLETestBase::drawIndexedQuad(GLuint program,
                                    const std::string &positionAttribName,
                                    GLfloat positionAttribZ,
                                    GLfloat positionAttribXYScale,
                                    bool useIndexBuffer,
                                    bool restrictedRange)
{
    GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());

    GLint activeProgram = 0;
    glGetIntegerv(GL_CURRENT_PROGRAM, &activeProgram);
    if (static_cast<GLuint>(activeProgram) != program)
    {
        glUseProgram(program);
    }

    GLuint prevCoordBinding = 0;
    glGetIntegerv(GL_ARRAY_BUFFER_BINDING, reinterpret_cast<GLint *>(&prevCoordBinding));

    setupIndexedQuadVertexBuffer(positionAttribZ, positionAttribXYScale);

    glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnableVertexAttribArray(positionLocation);
    glBindBuffer(GL_ARRAY_BUFFER, prevCoordBinding);

    GLuint prevIndexBinding = 0;
    const GLvoid *indices;
    if (useIndexBuffer)
    {
        glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING,
                      reinterpret_cast<GLint *>(&prevIndexBinding));

        setupIndexedQuadIndexBuffer();
        indices = 0;
    }
    else
    {
        indices = kIndexedQuadIndices.data();
    }

    if (!restrictedRange)
    {
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
    }
    else
    {
        glDrawRangeElements(GL_TRIANGLES, 0, 3, 6, GL_UNSIGNED_SHORT, indices);
    }

    if (useIndexBuffer)
    {
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prevIndexBinding);
    }

    glDisableVertexAttribArray(positionLocation);
    glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, nullptr);

    if (static_cast<GLuint>(activeProgram) != program)
    {
        glUseProgram(static_cast<GLuint>(activeProgram));
    }
}

GLuint ANGLETestBase::get2DTexturedQuadProgram()
{
    if (m2DTexturedQuadProgram)
    {
        return m2DTexturedQuadProgram;
    }

    constexpr char kVS[] =
        "attribute vec2 position;\n"
        "varying mediump vec2 texCoord;\n"
        "void main()\n"
        "{\n"
        "    gl_Position = vec4(position, 0, 1);\n"
        "    texCoord = position * 0.5 + vec2(0.5);\n"
        "}\n";

    constexpr char kFS[] =
        "varying mediump vec2 texCoord;\n"
        "uniform sampler2D tex;\n"
        "void main()\n"
        "{\n"
        "    gl_FragColor = texture2D(tex, texCoord);\n"
        "}\n";

    m2DTexturedQuadProgram = CompileProgram(kVS, kFS);
    return m2DTexturedQuadProgram;
}

GLuint ANGLETestBase::get3DTexturedQuadProgram()
{
    if (m3DTexturedQuadProgram)
    {
        return m3DTexturedQuadProgram;
    }

    constexpr char kVS[] = R"(#version 300 es
in vec2 position;
out vec2 texCoord;
void main()
{
    gl_Position = vec4(position, 0, 1);
    texCoord = position * 0.5 + vec2(0.5);
})";

    constexpr char kFS[] = R"(#version 300 es
precision highp float;

in vec2 texCoord;
out vec4 my_FragColor;

uniform highp sampler3D tex;
uniform float u_layer;

void main()
{
    my_FragColor = texture(tex, vec3(texCoord, u_layer));
})";

    m3DTexturedQuadProgram = CompileProgram(kVS, kFS);
    return m3DTexturedQuadProgram;
}

GLuint ANGLETestBase::get2DArrayTexturedQuadProgram()
{
    if (m2DArrayTexturedQuadProgram)
    {
        return m2DArrayTexturedQuadProgram;
    }

    constexpr char kVS[] = R"(#version 300 es
in vec2 position;
out vec2 texCoord;
void main()
{
    gl_Position = vec4(position, 0, 1);
    texCoord = position * 0.5 + vec2(0.5);
})";

    constexpr char kFS[] = R"(#version 300 es
precision highp float;

in vec2 texCoord;
out vec4 my_FragColor;

uniform highp sampler2DArray tex;
uniform float u_layer;

void main()
{
    my_FragColor = texture(tex, vec3(texCoord, u_layer));
})";

    m2DArrayTexturedQuadProgram = CompileProgram(kVS, kFS);
    return m2DArrayTexturedQuadProgram;
}

void ANGLETestBase::draw2DTexturedQuad(GLfloat positionAttribZ,
                                       GLfloat positionAttribXYScale,
                                       bool useVertexBuffer)
{
    ASSERT_NE(0u, get2DTexturedQuadProgram());
    drawQuad(get2DTexturedQuadProgram(), "position", positionAttribZ, positionAttribXYScale,
             useVertexBuffer);
}

void ANGLETestBase::draw3DTexturedQuad(GLfloat positionAttribZ,
                                       GLfloat positionAttribXYScale,
                                       bool useVertexBuffer,
                                       float layer)
{
    GLuint program = get3DTexturedQuadProgram();
    ASSERT_NE(0u, program);
    GLint activeProgram = 0;
    glGetIntegerv(GL_CURRENT_PROGRAM, &activeProgram);
    if (static_cast<GLuint>(activeProgram) != program)
    {
        glUseProgram(program);
    }
    glUniform1f(glGetUniformLocation(program, "u_layer"), layer);

    drawQuad(program, "position", positionAttribZ, positionAttribXYScale, useVertexBuffer);

    if (static_cast<GLuint>(activeProgram) != program)
    {
        glUseProgram(static_cast<GLuint>(activeProgram));
    }
}

void ANGLETestBase::draw2DArrayTexturedQuad(GLfloat positionAttribZ,
                                            GLfloat positionAttribXYScale,
                                            bool useVertexBuffer,
                                            float layer)
{
    GLuint program = get2DArrayTexturedQuadProgram();
    ASSERT_NE(0u, program);
    GLint activeProgram = 0;
    glGetIntegerv(GL_CURRENT_PROGRAM, &activeProgram);
    if (static_cast<GLuint>(activeProgram) != program)
    {
        glUseProgram(program);
    }
    glUniform1f(glGetUniformLocation(program, "u_layer"), layer);

    drawQuad(program, "position", positionAttribZ, positionAttribXYScale, useVertexBuffer);

    if (static_cast<GLuint>(activeProgram) != program)
    {
        glUseProgram(static_cast<GLuint>(activeProgram));
    }
}

bool ANGLETestBase::platformSupportsMultithreading() const
{
    return (mFixture && mFixture->eglWindow &&
            IsEGLDisplayExtensionEnabled(mFixture->eglWindow->getDisplay(),
                                         "EGL_ANGLE_context_virtualization")) ||
           IsVulkan();
}

void ANGLETestBase::checkD3D11SDKLayersMessages()
{
#if defined(ANGLE_ENABLE_D3D11)
    // On Windows D3D11, check ID3D11InfoQueue to see if any D3D11 SDK Layers messages
    // were outputted by the test. We enable the Debug layers in Release tests as well.
    if (mIgnoreD3D11SDKLayersWarnings ||
        mFixture->eglWindow->getPlatform().renderer != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE ||
        mFixture->eglWindow->getDisplay() == EGL_NO_DISPLAY)
    {
        return;
    }

    const char *extensionString = static_cast<const char *>(
        eglQueryString(mFixture->eglWindow->getDisplay(), EGL_EXTENSIONS));
    if (!extensionString)
    {
        std::cout << "Error getting extension string from EGL Window." << std::endl;
        return;
    }

    if (!ANGLE_UNSAFE_TODO(strstr(extensionString, "EGL_EXT_device_query")))
    {
        return;
    }

    EGLAttrib device      = 0;
    EGLAttrib angleDevice = 0;

    ASSERT_EGL_TRUE(
        eglQueryDisplayAttribEXT(mFixture->eglWindow->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
    ASSERT_EGL_TRUE(eglQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
                                            EGL_D3D11_DEVICE_ANGLE, &device));
    ID3D11Device *d3d11Device = reinterpret_cast<ID3D11Device *>(device);

    ID3D11InfoQueue *infoQueue = nullptr;
    HRESULT hr =
        d3d11Device->QueryInterface(__uuidof(infoQueue), reinterpret_cast<void **>(&infoQueue));
    if (SUCCEEDED(hr))
    {
        UINT64 numStoredD3DDebugMessages =
            infoQueue->GetNumStoredMessagesAllowedByRetrievalFilter();

        if (numStoredD3DDebugMessages > 0)
        {
            for (UINT64 i = 0; i < numStoredD3DDebugMessages; i++)
            {
                SIZE_T messageLength = 0;
                hr                   = infoQueue->GetMessage(i, nullptr, &messageLength);

                if (SUCCEEDED(hr))
                {
                    D3D11_MESSAGE *pMessage =
                        reinterpret_cast<D3D11_MESSAGE *>(malloc(messageLength));
                    infoQueue->GetMessage(i, pMessage, &messageLength);

                    std::cout << "Message " << i << ":" << " " << pMessage->pDescription << "\n";
                    free(pMessage);
                }
            }
            // Clear the queue, so that previous failures are not reported
            // for subsequent, otherwise passing, tests
            infoQueue->ClearStoredMessages();

            FAIL() << numStoredD3DDebugMessages
                   << " D3D11 SDK Layers message(s) detected! Test Failed.\n";
        }
    }

    SafeRelease(infoQueue);
#endif  // defined(ANGLE_ENABLE_D3D11)
}

void ANGLETestBase::setWindowWidth(int width)
{
    mWidth = width;
}

void ANGLETestBase::setWindowHeight(int height)
{
    mHeight = height;
}

GLWindowBase *ANGLETestBase::getGLWindow() const
{
    // WGL tests are currently disabled.
    assert(!mFixture->wglWindow);
    return mFixture->eglWindow;
}

void ANGLETestBase::setConfigRedBits(int bits)
{
    mFixture->configParams.redBits = bits;
}

void ANGLETestBase::setConfigGreenBits(int bits)
{
    mFixture->configParams.greenBits = bits;
}

void ANGLETestBase::setConfigBlueBits(int bits)
{
    mFixture->configParams.blueBits = bits;
}

void ANGLETestBase::setConfigAlphaBits(int bits)
{
    mFixture->configParams.alphaBits = bits;
}

void ANGLETestBase::setConfigDepthBits(int bits)
{
    mFixture->configParams.depthBits = bits;
}

void ANGLETestBase::setConfigStencilBits(int bits)
{
    mFixture->configParams.stencilBits = bits;
}

void ANGLETestBase::setConfigColorSpace(EGLenum colorSpace)
{
    mFixture->configParams.colorSpace = colorSpace;
}

void ANGLETestBase::setConfigComponentType(EGLenum componentType)
{
    mFixture->configParams.componentType = componentType;
}

void ANGLETestBase::setMultisampleEnabled(bool enabled)
{
    mFixture->configParams.multisample = enabled;
}

void ANGLETestBase::setSamples(EGLint samples)
{
    mFixture->configParams.samples = samples;
}

void ANGLETestBase::setDebugEnabled(bool enabled)
{
    mFixture->configParams.debug = enabled;
}

void ANGLETestBase::setNoErrorEnabled(bool enabled)
{
    mFixture->configParams.noError = enabled;
}

void ANGLETestBase::setWebGLCompatibilityEnabled(bool webglCompatibility)
{
    mFixture->configParams.webGLCompatibility = webglCompatibility;
}

void ANGLETestBase::setHardenedContextEnabled(bool hardenedContext)
{
    mFixture->configParams.hardenedContext = hardenedContext;
}

void ANGLETestBase::setExtensionsEnabled(bool extensionsEnabled)
{
    mFixture->configParams.extensionsEnabled = extensionsEnabled;
}

void ANGLETestBase::setRobustAccess(bool enabled)
{
    mFixture->configParams.robustAccess = enabled;
}

void ANGLETestBase::setBindGeneratesResource(bool bindGeneratesResource)
{
    mFixture->configParams.bindGeneratesResource = bindGeneratesResource;
}

void ANGLETestBase::setClientArraysEnabled(bool enabled)
{
    mFixture->configParams.clientArraysEnabled = enabled;
}

void ANGLETestBase::setRobustResourceInit(bool enabled)
{
    mFixture->configParams.robustResourceInit = enabled;
}

void ANGLETestBase::setPbuffer(bool enabled)
{
    mFixture->configParams.pbuffer = enabled;
}

void ANGLETestBase::setMutableRenderBuffer(bool enabled)
{
    mFixture->configParams.mutableRenderBuffer = enabled;
}

void ANGLETestBase::setContextProgramCacheEnabled(bool enabled)
{
    mFixture->configParams.contextProgramCacheEnabled = enabled;
}

void ANGLETestBase::setContextResetStrategy(EGLenum resetStrategy)
{
    mFixture->configParams.resetStrategy = resetStrategy;
}

void ANGLETestBase::forceNewDisplay()
{
    mForceNewDisplay = true;
}

void ANGLETestBase::setDeferContextInit(bool enabled)
{
    mDeferContextInit = enabled;
}

int ANGLETestBase::getClientMajorVersion() const
{
    return getGLWindow()->getClientMajorVersion();
}

int ANGLETestBase::getClientMinorVersion() const
{
    return getGLWindow()->getClientMinorVersion();
}

EGLWindow *ANGLETestBase::getEGLWindow() const
{
    return mFixture->eglWindow;
}

int ANGLETestBase::getWindowWidth() const
{
    return mWidth;
}

int ANGLETestBase::getWindowHeight() const
{
    return mHeight;
}

void ANGLETestBase::setWindowVisible(OSWindow *osWindow, bool isVisible)
{
    // SwiftShader windows are not required to be visible for test correctness,
    // moreover, making a SwiftShader window visible flaky hangs on Xvfb, so we keep them hidden.
    if (isSwiftshader())
    {
        return;
    }
    osWindow->setVisible(isVisible);
}

ANGLETestBase::TestFixture::TestFixture()  = default;
ANGLETestBase::TestFixture::~TestFixture() = default;

EGLint ANGLETestBase::getPlatformRenderer() const
{
    assert(mFixture->eglWindow);
    return mFixture->eglWindow->getPlatform().renderer;
}

void ANGLETestBase::ignoreD3D11SDKLayersWarnings()
{
    // Some tests may need to disable the D3D11 SDK Layers Warnings checks
    mIgnoreD3D11SDKLayersWarnings = true;
}

ANGLETestBase::ScopedIgnorePlatformMessages::ScopedIgnorePlatformMessages()
{
    gPlatformContext.ignoreMessages = true;
}

ANGLETestBase::ScopedIgnorePlatformMessages::~ScopedIgnorePlatformMessages()
{
    gPlatformContext.ignoreMessages = false;
}

OSWindow *ANGLETestBase::mOSWindowSingleton = nullptr;
std::map<angle::PlatformParameters, ANGLETestBase::TestFixture> ANGLETestBase::gFixtures;
Optional<EGLint> ANGLETestBase::mLastRendererType;
Optional<angle::GLESDriverType> ANGLETestBase::mLastLoadedDriver;

std::unique_ptr<Library> ANGLETestEnvironment::gAngleEGLLibrary;
std::unique_ptr<Library> ANGLETestEnvironment::gAngleVulkanSecondariesEGLLibrary;
std::unique_ptr<Library> ANGLETestEnvironment::gMesaEGLLibrary;
std::unique_ptr<Library> ANGLETestEnvironment::gSystemEGLLibrary;
std::unique_ptr<Library> ANGLETestEnvironment::gSystemWGLLibrary;

void ANGLETestEnvironment::SetUp() {}

void ANGLETestEnvironment::TearDown()
{
    ANGLETestBase::ReleaseFixtures();
}

// static
Library *ANGLETestEnvironment::GetDriverLibrary(angle::GLESDriverType driver)
{
    switch (driver)
    {
        case angle::GLESDriverType::AngleEGL:
            return GetAngleEGLLibrary();
        case angle::GLESDriverType::AngleVulkanSecondariesEGL:
            return GetAngleVulkanSecondariesEGLLibrary();
        case angle::GLESDriverType::SystemEGL:
            return GetSystemEGLLibrary();
        case angle::GLESDriverType::SystemWGL:
            return GetSystemWGLLibrary();
        case angle::GLESDriverType::ZinkEGL:
            return GetMesaEGLLibrary();
        default:
            return nullptr;
    }
}

// static
Library *ANGLETestEnvironment::GetAngleEGLLibrary()
{
#if defined(ANGLE_USE_UTIL_LOADER)
    if (!gAngleEGLLibrary)
    {
        gAngleEGLLibrary.reset(OpenSharedLibrary(ANGLE_EGL_LIBRARY_NAME, SearchType::ModuleDir));
    }
#endif  // defined(ANGLE_USE_UTIL_LOADER)
    return gAngleEGLLibrary.get();
}

// static
Library *ANGLETestEnvironment::GetAngleVulkanSecondariesEGLLibrary()
{
#if defined(ANGLE_USE_UTIL_LOADER)
    if (!gAngleVulkanSecondariesEGLLibrary)
    {
        gAngleVulkanSecondariesEGLLibrary.reset(
            OpenSharedLibrary(ANGLE_VULKAN_SECONDARIES_EGL_LIBRARY_NAME, SearchType::ModuleDir));
    }
#endif  // defined(ANGLE_USE_UTIL_LOADER)
    return gAngleVulkanSecondariesEGLLibrary.get();
}

// static
Library *ANGLETestEnvironment::GetMesaEGLLibrary()
{
#if defined(ANGLE_USE_UTIL_LOADER)
    if (!gMesaEGLLibrary)
    {
        gMesaEGLLibrary.reset(
            OpenSharedLibrary(ANGLE_MESA_EGL_LIBRARY_NAME, SearchType::ModuleDir));
    }
#endif  // defined(ANGLE_USE_UTIL_LOADER)
    return gMesaEGLLibrary.get();
}

// static
Library *ANGLETestEnvironment::GetSystemEGLLibrary()
{
#if defined(ANGLE_USE_UTIL_LOADER)
    if (!gSystemEGLLibrary)
    {
        gSystemEGLLibrary.reset(OpenSharedLibraryWithExtension(
            GetNativeEGLLibraryNameWithExtension(), SearchType::SystemDir));
    }
#endif  // defined(ANGLE_USE_UTIL_LOADER)
    return gSystemEGLLibrary.get();
}

// static
Library *ANGLETestEnvironment::GetSystemWGLLibrary()
{
#if defined(ANGLE_USE_UTIL_LOADER) && defined(ANGLE_PLATFORM_WINDOWS)
    if (!gSystemWGLLibrary)
    {
        gSystemWGLLibrary.reset(OpenSharedLibrary("opengl32", SearchType::SystemDir));
    }
#endif  // defined(ANGLE_USE_UTIL_LOADER) && defined(ANGLE_PLATFORM_WINDOWS)
    return gSystemWGLLibrary.get();
}

void ANGLEProcessTestArgs(int *argc, char *argv[])
{
    testing::AddGlobalTestEnvironment(new ANGLETestEnvironment());

    for (int argIndex = 1; argIndex < *argc; argIndex++)
    {
        if (ANGLE_UNSAFE_TODO(strncmp(argv[argIndex], kUseConfig, strlen(kUseConfig))) == 0)
        {
            SetSelectedConfig(ANGLE_UNSAFE_TODO(argv[argIndex] + strlen(kUseConfig)));
        }
        else if (ANGLE_UNSAFE_TODO(
                     strncmp(argv[argIndex], kReuseDisplays, strlen(kReuseDisplays))) == 0)
        {
            gReuseDisplays = true;
        }
        else if (ANGLE_UNSAFE_TODO(strncmp(argv[argIndex], kBatchId, strlen(kBatchId))) == 0)
        {
            // Enable display reuse when running under --bot-mode.
            gReuseDisplays = true;
        }
        else if (ANGLE_UNSAFE_TODO(strncmp(argv[argIndex], kEnableANGLEPerTestCaptureLabel,
                                           strlen(kEnableANGLEPerTestCaptureLabel))) == 0)
        {
            gEnableANGLEPerTestCaptureLabel = true;
        }
        else if (ANGLE_UNSAFE_TODO(
                     strncmp(argv[argIndex], kDelayTestStart, strlen(kDelayTestStart))) == 0)
        {
            SetTestStartDelay(ANGLE_UNSAFE_TODO(argv[argIndex] + strlen(kDelayTestStart)));
        }
        else if (ANGLE_UNSAFE_TODO(strncmp(argv[argIndex], kRenderDoc, strlen(kRenderDoc))) == 0)
        {
            gEnableRenderDocCapture = true;
        }
        else if (ANGLE_UNSAFE_TODO(strncmp(argv[argIndex], kNoRenderDoc, strlen(kNoRenderDoc))) ==
                 0)
        {
            gEnableRenderDocCapture = false;
        }
    }
}
