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

#ifndef ANGLE_TESTS_ANGLE_TEST_H_
#define ANGLE_TESTS_ANGLE_TEST_H_

#include <gtest/gtest.h>
#include <algorithm>
#include <array>

#include "angle_test_configs.h"
#include "common/angleutils.h"
#include "common/system_utils.h"
#include "common/vector_utils.h"
#include "platform/Platform.h"
#include "util/EGLWindow.h"
#include "util/shader_utils.h"
#include "util/util_gl.h"

namespace angle
{
struct SystemInfo;
}  // namespace angle

#define ASSERT_GL_TRUE(a) ASSERT_EQ(static_cast<GLboolean>(GL_TRUE), (a))
#define ASSERT_GL_FALSE(a) ASSERT_EQ(static_cast<GLboolean>(GL_FALSE), (a))
#define EXPECT_GL_TRUE(a) EXPECT_EQ(static_cast<GLboolean>(GL_TRUE), (a))
#define EXPECT_GL_FALSE(a) EXPECT_EQ(static_cast<GLboolean>(GL_FALSE), (a))

#define EXPECT_GL_ERROR(err) EXPECT_EQ(static_cast<GLenum>(err), glGetError())
#define EXPECT_GL_NO_ERROR() EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError())

#define ASSERT_GL_ERROR(err) ASSERT_EQ(static_cast<GLenum>(err), glGetError())
#define ASSERT_GL_NO_ERROR() ASSERT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError())

#define EXPECT_EGL_ERROR(err) EXPECT_EQ((err), eglGetError())
#define EXPECT_EGL_SUCCESS() EXPECT_EGL_ERROR(EGL_SUCCESS)

// EGLBoolean is |unsigned int| but EGL_TRUE is 0, not 0u.
#define ASSERT_EGL_TRUE(a) ASSERT_EQ(static_cast<EGLBoolean>(EGL_TRUE), static_cast<EGLBoolean>(a))
#define ASSERT_EGL_FALSE(a) \
    ASSERT_EQ(static_cast<EGLBoolean>(EGL_FALSE), static_cast<EGLBoolean>(a))
#define EXPECT_EGL_TRUE(a) EXPECT_EQ(static_cast<EGLBoolean>(EGL_TRUE), static_cast<EGLBoolean>(a))
#define EXPECT_EGL_FALSE(a) \
    EXPECT_EQ(static_cast<EGLBoolean>(EGL_FALSE), static_cast<EGLBoolean>(a))

#define ASSERT_EGL_ERROR(err) ASSERT_EQ((err), eglGetError())
#define ASSERT_EGL_SUCCESS() ASSERT_EGL_ERROR(EGL_SUCCESS)

#define ASSERT_GLENUM_EQ(expected, actual) \
    ASSERT_EQ(static_cast<GLenum>(expected), static_cast<GLenum>(actual))
#define EXPECT_GLENUM_EQ(expected, actual) \
    EXPECT_EQ(static_cast<GLenum>(expected), static_cast<GLenum>(actual))
#define ASSERT_GLENUM_NE(expected, actual) \
    ASSERT_NE(static_cast<GLenum>(expected), static_cast<GLenum>(actual))
#define EXPECT_GLENUM_NE(expected, actual) \
    EXPECT_NE(static_cast<GLenum>(expected), static_cast<GLenum>(actual))

#define ASSERT_EGLENUM_EQ(expected, actual) \
    ASSERT_EQ(static_cast<EGLenum>(expected), static_cast<EGLenum>(actual))
#define EXPECT_EGLENUM_EQ(expected, actual) \
    EXPECT_EQ(static_cast<EGLenum>(expected), static_cast<EGLenum>(actual))

#define ASSERT_GL_FRAMEBUFFER_COMPLETE(framebuffer) \
    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(framebuffer))
#define EXPECT_GL_FRAMEBUFFER_COMPLETE(framebuffer) \
    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(framebuffer))

namespace angle
{
struct GLColorRGB
{
    constexpr GLColorRGB() : R(0), G(0), B(0) {}
    constexpr GLColorRGB(GLubyte r, GLubyte g, GLubyte b) : R(r), G(g), B(b) {}
    GLColorRGB(const angle::Vector3 &floatColor);

    const GLubyte *data() const { return &R; }
    GLubyte *data() { return &R; }

    GLubyte R, G, B;

    static const GLColorRGB black;
    static const GLColorRGB blue;
    static const GLColorRGB green;
    static const GLColorRGB red;
    static const GLColorRGB yellow;
};

struct GLColor
{
    constexpr GLColor() : R(0), G(0), B(0), A(0) {}
    constexpr GLColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a) : R(r), G(g), B(b), A(a) {}
    GLColor(const angle::Vector4 &floatColor);
    GLColor(GLuint colorValue);

    angle::Vector4 toNormalizedVector() const;

    GLubyte &operator[](size_t index) { return (&R)[index]; }

    const GLubyte &operator[](size_t index) const { return (&R)[index]; }

    const GLubyte *data() const { return &R; }
    GLubyte *data() { return &R; }

    testing::AssertionResult ExpectNear(const GLColor &expected, const GLColor &err) const;

    GLubyte R, G, B, A;

    static const GLColor black;
    static const GLColor blue;
    static const GLColor cyan;
    static const GLColor green;
    static const GLColor red;
    static const GLColor transparentBlack;
    static const GLColor white;
    static const GLColor yellow;
    static const GLColor magenta;
};

struct GLColor32F
{
    constexpr GLColor32F() : GLColor32F(0.0f, 0.0f, 0.0f, 0.0f) {}
    constexpr GLColor32F(GLfloat r, GLfloat g, GLfloat b, GLfloat a) : R(r), G(g), B(b), A(a) {}

    GLfloat R, G, B, A;
};

static constexpr GLColor32F kFloatRed   = {1.0f, 0.0f, 0.0f, 1.0f};
static constexpr GLColor32F kFloatGreen = {0.0f, 1.0f, 0.0f, 1.0f};
static constexpr GLColor32F kFloatBlue  = {0.0f, 0.0f, 1.0f, 1.0f};

// The input here for pixelPoints are the expected integer window coordinates, we add .5 to every
// one of them and re-scale the numbers to be between [-1,1]. Using this technique, we can make
// sure the rasterization stage will end up drawing pixels at the expected locations.
void CreatePixelCenterWindowCoords(const std::vector<Vector2> &pixelPoints,
                                   int windowWidth,
                                   int windowHeight,
                                   std::vector<Vector3> *outVertices);

// Useful to cast any type to GLubyte.
template <typename TR, typename TG, typename TB, typename TA>
GLColor MakeGLColor(TR r, TG g, TB b, TA a)
{
    return GLColor(static_cast<GLubyte>(r), static_cast<GLubyte>(g), static_cast<GLubyte>(b),
                   static_cast<GLubyte>(a));
}

bool operator==(const GLColor &a, const GLColor &b);
bool operator!=(const GLColor &a, const GLColor &b);
std::ostream &operator<<(std::ostream &ostream, const GLColor &color);
GLColor ReadColor(GLint x, GLint y);

// Useful to cast any type to GLfloat.
template <typename TR, typename TG, typename TB, typename TA>
GLColor32F MakeGLColor32F(TR r, TG g, TB b, TA a)
{
    return GLColor32F(static_cast<GLfloat>(r), static_cast<GLfloat>(g), static_cast<GLfloat>(b),
                      static_cast<GLfloat>(a));
}

bool operator==(const GLColor32F &a, const GLColor32F &b);
std::ostream &operator<<(std::ostream &ostream, const GLColor32F &color);
GLColor32F ReadColor32F(GLint x, GLint y);

}  // namespace angle

#define EXPECT_PIXEL_EQ(x, y, r, g, b, a) \
    EXPECT_EQ(angle::MakeGLColor(r, g, b, a), angle::ReadColor(x, y))

#define EXPECT_PIXEL_NE(x, y, r, g, b, a) \
    EXPECT_NE(angle::MakeGLColor(r, g, b, a), angle::ReadColor(x, y))

#define EXPECT_PIXEL_32F_EQ(x, y, r, g, b, a) \
    EXPECT_EQ(angle::MakeGLColor32F(r, g, b, a), angle::ReadColor32F(x, y))

#define EXPECT_PIXEL_ALPHA_EQ(x, y, a) EXPECT_EQ(a, angle::ReadColor(x, y).A)

#define EXPECT_PIXEL_ALPHA32F_EQ(x, y, a) EXPECT_EQ(a, angle::ReadColor32F(x, y).A)

#define EXPECT_PIXEL_COLOR_EQ(x, y, angleColor) EXPECT_EQ(angleColor, angle::ReadColor(x, y))
#define EXPECT_PIXEL_COLOR_EQ_VEC2(vec2, angleColor) \
    EXPECT_EQ(angleColor,                            \
              angle::ReadColor(static_cast<GLint>(vec2.x()), static_cast<GLint>(vec2.y())))

#define EXPECT_PIXEL_COLOR32F_EQ(x, y, angleColor) EXPECT_EQ(angleColor, angle::ReadColor32F(x, y))

#define EXPECT_PIXEL_RECT_EQ(x, y, width, height, color)                                           \
    do                                                                                             \
    {                                                                                              \
        std::vector<GLColor> actualColors(width *height);                                          \
        glReadPixels((x), (y), (width), (height), GL_RGBA, GL_UNSIGNED_BYTE, actualColors.data()); \
        std::vector<GLColor> expectedColors(width *height, color);                                 \
        EXPECT_EQ(expectedColors, actualColors);                                                   \
    } while (0)

#define EXPECT_PIXEL_NEAR_HELPER(x, y, r, g, b, a, abs_error, ctype, format, type) \
    do                                                                             \
    {                                                                              \
        ctype pixel[4];                                                            \
        glReadPixels((x), (y), 1, 1, format, type, pixel);                         \
        EXPECT_GL_NO_ERROR();                                                      \
        EXPECT_NEAR((r), pixel[0], abs_error);                                     \
        EXPECT_NEAR((g), pixel[1], abs_error);                                     \
        EXPECT_NEAR((b), pixel[2], abs_error);                                     \
        EXPECT_NEAR((a), pixel[3], abs_error);                                     \
    } while (0)

#define EXPECT_PIXEL_EQ_HELPER(x, y, r, g, b, a, ctype, format, type) \
    do                                                                \
    {                                                                 \
        ctype pixel[4];                                               \
        glReadPixels((x), (y), 1, 1, format, type, pixel);            \
        EXPECT_GL_NO_ERROR();                                         \
        EXPECT_EQ((r), pixel[0]);                                     \
        EXPECT_EQ((g), pixel[1]);                                     \
        EXPECT_EQ((b), pixel[2]);                                     \
        EXPECT_EQ((a), pixel[3]);                                     \
    } while (0)

#define EXPECT_PIXEL_RGB_EQ_HELPER(x, y, r, g, b, ctype, format, type) \
    do                                                                 \
    {                                                                  \
        ctype pixel[4];                                                \
        glReadPixels((x), (y), 1, 1, format, type, pixel);             \
        EXPECT_GL_NO_ERROR();                                          \
        EXPECT_EQ((r), pixel[0]);                                      \
        EXPECT_EQ((g), pixel[1]);                                      \
        EXPECT_EQ((b), pixel[2]);                                      \
    } while (0)

#define EXPECT_PIXEL_NEAR(x, y, r, g, b, a, abs_error) \
    EXPECT_PIXEL_NEAR_HELPER(x, y, r, g, b, a, abs_error, GLubyte, GL_RGBA, GL_UNSIGNED_BYTE)

#define EXPECT_PIXEL_32F_NEAR(x, y, r, g, b, a, abs_error) \
    EXPECT_PIXEL_NEAR_HELPER(x, y, r, g, b, a, abs_error, GLfloat, GL_RGBA, GL_FLOAT)

#define EXPECT_PIXEL_8I(x, y, r, g, b, a) \
    EXPECT_PIXEL_EQ_HELPER(x, y, r, g, b, a, GLbyte, GL_RGBA_INTEGER, GL_BYTE)

#define EXPECT_PIXEL_8UI(x, y, r, g, b, a) \
    EXPECT_PIXEL_EQ_HELPER(x, y, r, g, b, a, GLubyte, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE)

#define EXPECT_PIXEL_RGB_EQUAL(x, y, r, g, b) \
    EXPECT_PIXEL_RGB_EQ_HELPER(x, y, r, g, b, GLubyte, GL_RGBA, GL_UNSIGNED_BYTE)

// TODO(jmadill): Figure out how we can use GLColor's nice printing with EXPECT_NEAR.
#define EXPECT_PIXEL_COLOR_NEAR(x, y, angleColor, abs_error) \
    EXPECT_PIXEL_NEAR(x, y, angleColor.R, angleColor.G, angleColor.B, angleColor.A, abs_error)

#define EXPECT_PIXEL_COLOR32F_NEAR(x, y, angleColor, abs_error) \
    EXPECT_PIXEL32F_NEAR(x, y, angleColor.R, angleColor.G, angleColor.B, angleColor.A, abs_error)

#define EXPECT_COLOR_NEAR(expected, actual, abs_error) \
    do                                                 \
    {                                                  \
        EXPECT_NEAR(expected.R, actual.R, abs_error);  \
        EXPECT_NEAR(expected.G, actual.G, abs_error);  \
        EXPECT_NEAR(expected.B, actual.B, abs_error);  \
        EXPECT_NEAR(expected.A, actual.A, abs_error);  \
    } while (0)
#define EXPECT_PIXEL32F_NEAR(x, y, r, g, b, a, abs_error)       \
    do                                                          \
    {                                                           \
        GLfloat pixel[4];                                       \
        glReadPixels((x), (y), 1, 1, GL_RGBA, GL_FLOAT, pixel); \
        EXPECT_GL_NO_ERROR();                                   \
        EXPECT_NEAR((r), pixel[0], abs_error);                  \
        EXPECT_NEAR((g), pixel[1], abs_error);                  \
        EXPECT_NEAR((b), pixel[2], abs_error);                  \
        EXPECT_NEAR((a), pixel[3], abs_error);                  \
    } while (0)

#define EXPECT_PIXEL_COLOR32F_NEAR(x, y, angleColor, abs_error) \
    EXPECT_PIXEL32F_NEAR(x, y, angleColor.R, angleColor.G, angleColor.B, angleColor.A, abs_error)

class ANGLETestBase;
class EGLWindow;
class GLWindowBase;
class OSWindow;
class WGLWindow;

struct TestPlatformContext final : private angle::NonCopyable
{
    bool ignoreMessages        = false;
    bool warningsAsErrors      = false;
    ANGLETestBase *currentTest = nullptr;
};

class ANGLETestBase
{
  protected:
    ANGLETestBase(const angle::PlatformParameters &params);
    virtual ~ANGLETestBase();

  public:
    void setWindowVisible(bool isVisible);

    virtual void overrideWorkaroundsD3D(angle::FeaturesD3D *featuresD3D) {}
    virtual void overrideFeaturesVk(angle::FeaturesVk *featuresVulkan) {}

    static void ReleaseFixtures();

  protected:
    void ANGLETestSetUp();
    void ANGLETestTearDown();

    virtual void swapBuffers();

    void setupQuadVertexBuffer(GLfloat positionAttribZ, GLfloat positionAttribXYScale);
    void setupIndexedQuadVertexBuffer(GLfloat positionAttribZ, GLfloat positionAttribXYScale);
    void setupIndexedQuadIndexBuffer();

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

    static std::array<angle::Vector3, 6> GetQuadVertices();
    static std::array<GLushort, 6> GetQuadIndices();
    static std::array<angle::Vector3, 4> GetIndexedQuadVertices();

    void drawIndexedQuad(GLuint program,
                         const std::string &positionAttribName,
                         GLfloat positionAttribZ);
    void drawIndexedQuad(GLuint program,
                         const std::string &positionAttribName,
                         GLfloat positionAttribZ,
                         GLfloat positionAttribXYScale);
    void drawIndexedQuad(GLuint program,
                         const std::string &positionAttribName,
                         GLfloat positionAttribZ,
                         GLfloat positionAttribXYScale,
                         bool useBufferObject);

    void drawIndexedQuad(GLuint program,
                         const std::string &positionAttribName,
                         GLfloat positionAttribZ,
                         GLfloat positionAttribXYScale,
                         bool useBufferObject,
                         bool restrictedRange);

    void draw2DTexturedQuad(GLfloat positionAttribZ,
                            GLfloat positionAttribXYScale,
                            bool useVertexBuffer);

    // The layer parameter chooses the 3D texture layer to sample from.
    void draw3DTexturedQuad(GLfloat positionAttribZ,
                            GLfloat positionAttribXYScale,
                            bool useVertexBuffer,
                            float layer);

    void setWindowWidth(int width);
    void setWindowHeight(int height);
    void setConfigRedBits(int bits);
    void setConfigGreenBits(int bits);
    void setConfigBlueBits(int bits);
    void setConfigAlphaBits(int bits);
    void setConfigDepthBits(int bits);
    void setConfigStencilBits(int bits);
    void setConfigComponentType(EGLenum componentType);
    void setMultisampleEnabled(bool enabled);
    void setSamples(EGLint samples);
    void setDebugEnabled(bool enabled);
    void setNoErrorEnabled(bool enabled);
    void setWebGLCompatibilityEnabled(bool webglCompatibility);
    void setExtensionsEnabled(bool extensionsEnabled);
    void setRobustAccess(bool enabled);
    void setBindGeneratesResource(bool bindGeneratesResource);
    void setClientArraysEnabled(bool enabled);
    void setRobustResourceInit(bool enabled);
    void setContextProgramCacheEnabled(bool enabled);
    void setContextResetStrategy(EGLenum resetStrategy);
    void forceNewDisplay();

    // Some EGL extension tests would like to defer the Context init until the test body.
    void setDeferContextInit(bool enabled);

    int getClientMajorVersion() const;
    int getClientMinorVersion() const;

    GLWindowBase *getGLWindow() const;
    EGLWindow *getEGLWindow() const;
    int getWindowWidth() const;
    int getWindowHeight() const;
    bool isMultisampleEnabled() const;

    EGLint getPlatformRenderer() const;

    void ignoreD3D11SDKLayersWarnings();

    // Allows a test to be more restrictive about platform warnings.
    void treatPlatformWarningsAsErrors();

    OSWindow *getOSWindow() { return mFixture->osWindow; }

    GLuint get2DTexturedQuadProgram();

    // Has a float uniform "u_layer" to choose the 3D texture layer.
    GLuint get3DTexturedQuadProgram();

    class ScopedIgnorePlatformMessages : angle::NonCopyable
    {
      public:
        ScopedIgnorePlatformMessages();
        ~ScopedIgnorePlatformMessages();
    };

    // Can be used before we get a GL context.
    bool isGLRenderer() const
    {
        return mCurrentParams->getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
    }

    bool isGLESRenderer() const
    {
        return mCurrentParams->getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
    }

    bool isD3D11Renderer() const
    {
        return mCurrentParams->getRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
    }

    bool isVulkanRenderer() const
    {
        return mCurrentParams->getRenderer() == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
    }

  private:
    void checkD3D11SDKLayersMessages();

    void drawQuad(GLuint program,
                  const std::string &positionAttribName,
                  GLfloat positionAttribZ,
                  GLfloat positionAttribXYScale,
                  bool useVertexBuffer,
                  bool useInstancedDrawCalls,
                  GLuint numInstances);

    void initOSWindow();

    struct TestFixture
    {
        TestFixture();
        ~TestFixture();

        EGLWindow *eglWindow = nullptr;
        WGLWindow *wglWindow = nullptr;
        OSWindow *osWindow   = nullptr;
        ConfigParameters configParams;
        uint32_t reuseCounter = 0;
    };

    int mWidth;
    int mHeight;

    bool mIgnoreD3D11SDKLayersWarnings;

    // Used for indexed quad rendering
    GLuint mQuadVertexBuffer;
    GLuint mQuadIndexBuffer;

    // Used for texture rendering.
    GLuint m2DTexturedQuadProgram;
    GLuint m3DTexturedQuadProgram;

    bool mDeferContextInit;
    bool mAlwaysForceNewDisplay;
    bool mForceNewDisplay;

    bool mSetUpCalled;
    bool mTearDownCalled;

    // On most systems we force a new display on every test instance. For these configs we can
    // share a single OSWindow instance. With display reuse we need a separate OSWindow for each
    // different config. This OSWindow sharing seemed to lead to driver bugs on some platforms.
    static OSWindow *mOSWindowSingleton;

    static std::map<angle::PlatformParameters, TestFixture> gFixtures;
    const angle::PlatformParameters *mCurrentParams;
    TestFixture *mFixture;

    // Workaround for NVIDIA not being able to share a window with OpenGL and Vulkan.
    static Optional<EGLint> mLastRendererType;
};

template <typename Params = angle::PlatformParameters>
class ANGLETestWithParam : public ANGLETestBase, public ::testing::TestWithParam<Params>
{
  protected:
    ANGLETestWithParam();

    virtual void testSetUp() {}
    virtual void testTearDown() {}

    void recreateTestFixture()
    {
        TearDown();
        SetUp();
    }

  private:
    void SetUp() final
    {
        ANGLETestBase::ANGLETestSetUp();
        testSetUp();
    }

    void TearDown() final
    {
        testTearDown();
        ANGLETestBase::ANGLETestTearDown();
    }
};

template <typename Params>
ANGLETestWithParam<Params>::ANGLETestWithParam()
    : ANGLETestBase(std::get<angle::PlatformParameters>(this->GetParam()))
{}

template <>
inline ANGLETestWithParam<angle::PlatformParameters>::ANGLETestWithParam()
    : ANGLETestBase(this->GetParam())
{}

// Note: this hack is not necessary in C++17.  Once we switch to C++17, we can just rename
// ANGLETestWithParam to ANGLETest.
using ANGLETest = ANGLETestWithParam<>;

class ANGLETestEnvironment : public testing::Environment
{
  public:
    void SetUp() override;
    void TearDown() override;

    static angle::Library *GetEGLLibrary();
    static angle::Library *GetWGLLibrary();

  private:
    // For loading entry points.
    static std::unique_ptr<angle::Library> gEGLLibrary;
    static std::unique_ptr<angle::Library> gWGLLibrary;
};

// Driver vendors
bool IsAdreno();

// Renderer back-ends
// Note: FL9_3 is explicitly *not* considered D3D11.
bool IsD3D11();
bool IsD3D11_FL93();
// Is a D3D9-class renderer.
bool IsD3D9();
// Is D3D9 or SM9_3 renderer.
bool IsD3DSM3();
bool IsDesktopOpenGL();
bool IsOpenGLES();
bool IsOpenGL();
bool IsNULL();
bool IsVulkan();

// Debug/Release
bool IsDebug();
bool IsRelease();

bool EnsureGLExtensionEnabled(const std::string &extName);
bool IsEGLClientExtensionEnabled(const std::string &extName);
bool IsEGLDeviceExtensionEnabled(EGLDeviceEXT device, const std::string &extName);
bool IsEGLDisplayExtensionEnabled(EGLDisplay display, const std::string &extName);
bool IsGLExtensionEnabled(const std::string &extName);
bool IsGLExtensionRequestable(const std::string &extName);

extern angle::PlatformMethods gDefaultPlatformMethods;

#define ANGLE_SKIP_TEST_IF(COND)                                  \
    do                                                            \
    {                                                             \
        if (COND)                                                 \
        {                                                         \
            std::cout << "Test skipped: " #COND "." << std::endl; \
            return;                                               \
        }                                                         \
    } while (0)

#endif  // ANGLE_TESTS_ANGLE_TEST_H_
