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

// EGLContextCompatibilityTest.cpp:
//   This test will try to use all combinations of context configs and
//   surface configs. If the configs are compatible, it checks that simple
//   rendering works, otherwise it checks an error is generated one MakeCurrent.
//

#include <gtest/gtest.h>

#include <unordered_set>
#include <vector>

#include "common/debug.h"
#include "test_utils/ANGLETest.h"
#include "test_utils/angle_test_configs.h"
#include "test_utils/angle_test_instantiate.h"
#include "util/OSWindow.h"
#include "util/random_utils.h"

using namespace angle;

namespace
{
// The only configs with 16-bits for each of red, green, blue, and alpha is GL_RGBA16F
bool IsRGBA16FConfig(EGLDisplay display, EGLConfig config)
{
    EGLint red, green, blue, alpha;
    eglGetConfigAttrib(display, config, EGL_RED_SIZE, &red);
    eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &green);
    eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blue);
    eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alpha);
    return ((red == 16) && (green == 16) && (blue == 16) && (alpha == 16));
}

bool IsRGB10_A2Config(EGLDisplay display, EGLConfig config)
{
    EGLint red, green, blue, alpha;
    eglGetConfigAttrib(display, config, EGL_RED_SIZE, &red);
    eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &green);
    eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blue);
    eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alpha);
    return ((red == 10) && (green == 10) && (blue == 10) && (alpha == 2));
}

// Queries EGL config to determine if multisampled or not
bool IsMultisampledConfig(EGLDisplay display, EGLConfig config)
{
    EGLint samples = 0;
    eglGetConfigAttrib(display, config, EGL_SAMPLES, &samples);
    return (samples > 1);
}

bool ShouldSkipConfig(EGLDisplay display, EGLConfig config, bool windowSurfaceTest)
{
    // Skip multisampled configurations due to test instability.
    if (IsMultisampledConfig(display, config))
        return true;

    // Disable RGBA16F/RGB10_A2 on Android due to OSWindow on Android not providing compatible
    // windows (http://anglebug.com/42261830)
    if (IsAndroid())
    {
        if (IsRGB10_A2Config(display, config))
            return true;

        if (IsRGBA16FConfig(display, config))
            return windowSurfaceTest;
    }

    return false;
}

std::vector<EGLConfig> GetConfigs(EGLDisplay display)
{
    int nConfigs = 0;
    if (eglGetConfigs(display, nullptr, 0, &nConfigs) != EGL_TRUE)
    {
        std::cerr << "EGLContextCompatibilityTest: eglGetConfigs error\n";
        return {};
    }
    if (nConfigs == 0)
    {
        std::cerr << "EGLContextCompatibilityTest: no configs\n";
        return {};
    }

    std::vector<EGLConfig> configs;

    int nReturnedConfigs = 0;
    configs.resize(nConfigs);
    if (eglGetConfigs(display, configs.data(), nConfigs, &nReturnedConfigs) != EGL_TRUE)
    {
        std::cerr << "EGLContextCompatibilityTest: eglGetConfigs error\n";
        return {};
    }
    if (nConfigs != nReturnedConfigs)
    {
        std::cerr << "EGLContextCompatibilityTest: eglGetConfigs returned wrong count\n";
        return {};
    }

    return configs;
}

PlatformParameters FromRenderer(EGLint renderer)
{
    return WithNoFixture(PlatformParameters(2, 0, EGLPlatformParameters(renderer)));
}

std::string EGLConfigName(EGLDisplay display, EGLConfig config)
{
    EGLint red;
    eglGetConfigAttrib(display, config, EGL_RED_SIZE, &red);
    EGLint green;
    eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &green);
    EGLint blue;
    eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blue);
    EGLint alpha;
    eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alpha);
    EGLint depth;
    eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depth);
    EGLint stencil;
    eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencil);
    EGLint samples;
    eglGetConfigAttrib(display, config, EGL_SAMPLES, &samples);

    std::stringstream strstr;
    if (red > 0)
    {
        strstr << "R" << red;
    }
    if (green > 0)
    {
        strstr << "G" << green;
    }
    if (blue > 0)
    {
        strstr << "B" << blue;
    }
    if (alpha > 0)
    {
        strstr << "A" << alpha;
    }
    if (depth > 0)
    {
        strstr << "D" << depth;
    }
    if (stencil > 0)
    {
        strstr << "S" << stencil;
    }
    if (samples > 0)
    {
        strstr << "MS" << samples;
    }
    return strstr.str();
}

const std::array<EGLint, 3> kContextAttribs = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};

class EGLContextCompatibilityTest : public ANGLETestBase
{
  public:
    EGLContextCompatibilityTest(EGLint renderer)
        : ANGLETestBase(FromRenderer(renderer)), mRenderer(renderer)
    {}

    void SetUp() final
    {
        ANGLETestBase::ANGLETestSetUp();
        ASSERT_TRUE(eglGetPlatformDisplay != nullptr);

        EGLAttrib dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, mRenderer, EGL_NONE};
        mDisplay              = eglGetPlatformDisplay(GetEglPlatform(),
                                                      reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
        ASSERT_TRUE(mDisplay != EGL_NO_DISPLAY);

        ASSERT_TRUE(eglInitialize(mDisplay, nullptr, nullptr) == EGL_TRUE);

        int nConfigs = 0;
        ASSERT_TRUE(eglGetConfigs(mDisplay, nullptr, 0, &nConfigs) == EGL_TRUE);
        ASSERT_TRUE(nConfigs != 0);

        int nReturnedConfigs = 0;
        mConfigs.resize(nConfigs);
        ASSERT_TRUE(eglGetConfigs(mDisplay, mConfigs.data(), nConfigs, &nReturnedConfigs) ==
                    EGL_TRUE);
        ASSERT_TRUE(nConfigs == nReturnedConfigs);
    }

    void TearDown() final
    {
        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        eglTerminate(mDisplay);
        ANGLETestBase::ANGLETestTearDown();
    }

  protected:
    bool areConfigsCompatible(EGLConfig c1, EGLConfig c2, EGLint surfaceBit)
    {
        EGLint colorBufferType1, colorBufferType2;
        EGLint red1, red2, green1, green2, blue1, blue2, alpha1, alpha2;
        EGLint depth1, depth2, stencil1, stencil2;
        EGLint surfaceType1, surfaceType2;

        eglGetConfigAttrib(mDisplay, c1, EGL_COLOR_BUFFER_TYPE, &colorBufferType1);
        eglGetConfigAttrib(mDisplay, c2, EGL_COLOR_BUFFER_TYPE, &colorBufferType2);

        eglGetConfigAttrib(mDisplay, c1, EGL_RED_SIZE, &red1);
        eglGetConfigAttrib(mDisplay, c2, EGL_RED_SIZE, &red2);
        eglGetConfigAttrib(mDisplay, c1, EGL_GREEN_SIZE, &green1);
        eglGetConfigAttrib(mDisplay, c2, EGL_GREEN_SIZE, &green2);
        eglGetConfigAttrib(mDisplay, c1, EGL_BLUE_SIZE, &blue1);
        eglGetConfigAttrib(mDisplay, c2, EGL_BLUE_SIZE, &blue2);
        eglGetConfigAttrib(mDisplay, c1, EGL_ALPHA_SIZE, &alpha1);
        eglGetConfigAttrib(mDisplay, c2, EGL_ALPHA_SIZE, &alpha2);

        eglGetConfigAttrib(mDisplay, c1, EGL_DEPTH_SIZE, &depth1);
        eglGetConfigAttrib(mDisplay, c2, EGL_DEPTH_SIZE, &depth2);
        eglGetConfigAttrib(mDisplay, c1, EGL_STENCIL_SIZE, &stencil1);
        eglGetConfigAttrib(mDisplay, c2, EGL_STENCIL_SIZE, &stencil2);

        eglGetConfigAttrib(mDisplay, c1, EGL_SURFACE_TYPE, &surfaceType1);
        eglGetConfigAttrib(mDisplay, c2, EGL_SURFACE_TYPE, &surfaceType2);

        EGLint colorComponentType1 = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
        EGLint colorComponentType2 = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
        if (IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_pixel_format_float"))
        {
            eglGetConfigAttrib(mDisplay, c1, EGL_COLOR_COMPONENT_TYPE_EXT, &colorComponentType1);
            eglGetConfigAttrib(mDisplay, c2, EGL_COLOR_COMPONENT_TYPE_EXT, &colorComponentType2);
        }

        EXPECT_EGL_SUCCESS();

        return colorBufferType1 == colorBufferType2 && red1 == red2 && green1 == green2 &&
               blue1 == blue2 && alpha1 == alpha2 && colorComponentType1 == colorComponentType2 &&
               depth1 == depth2 && stencil1 == stencil2 && (surfaceType1 & surfaceBit) != 0 &&
               (surfaceType2 & surfaceBit) != 0;
    }

    void testWindowCompatibility(EGLConfig windowConfig,
                                 EGLConfig contextConfig,
                                 bool compatible) const
    {
        OSWindow *osWindow = OSWindow::New();
        ASSERT_TRUE(osWindow != nullptr);
        osWindow->initialize("EGLContextCompatibilityTest", 500, 500);

        EGLContext context =
            eglCreateContext(mDisplay, contextConfig, EGL_NO_CONTEXT, kContextAttribs.data());
        ASSERT_TRUE(context != EGL_NO_CONTEXT);

        EGLSurface window =
            eglCreateWindowSurface(mDisplay, windowConfig, osWindow->getNativeWindow(), nullptr);
        ASSERT_EGL_SUCCESS();

        if (compatible)
        {
            testClearSurface(window, windowConfig, context);
        }
        else
        {
            testMakeCurrentFails(window, context);
        }

        eglDestroySurface(mDisplay, window);
        ASSERT_EGL_SUCCESS();

        eglDestroyContext(mDisplay, context);
        ASSERT_EGL_SUCCESS();

        OSWindow::Delete(&osWindow);
    }

    void testPbufferCompatibility(EGLConfig pbufferConfig,
                                  EGLConfig contextConfig,
                                  bool compatible) const
    {
        EGLContext context =
            eglCreateContext(mDisplay, contextConfig, EGL_NO_CONTEXT, kContextAttribs.data());
        ASSERT_TRUE(context != EGL_NO_CONTEXT);

        const EGLint pBufferAttribs[] = {
            EGL_WIDTH, 500, EGL_HEIGHT, 500, EGL_NONE,
        };
        EGLSurface pbuffer = eglCreatePbufferSurface(mDisplay, pbufferConfig, pBufferAttribs);
        ASSERT_TRUE(pbuffer != EGL_NO_SURFACE);

        if (compatible)
        {
            testClearSurface(pbuffer, pbufferConfig, context);
        }
        else
        {
            testMakeCurrentFails(pbuffer, context);
        }

        eglDestroySurface(mDisplay, pbuffer);
        ASSERT_EGL_SUCCESS();

        eglDestroyContext(mDisplay, context);
        ASSERT_EGL_SUCCESS();
    }

    std::vector<EGLConfig> mConfigs;
    EGLDisplay mDisplay = EGL_NO_DISPLAY;
    EGLint mRenderer    = 0;

  private:
    void testClearSurface(EGLSurface surface, EGLConfig surfaceConfig, EGLContext context) const
    {
        eglMakeCurrent(mDisplay, surface, surface, context);
        ASSERT_EGL_SUCCESS();

        glViewport(0, 0, 500, 500);
        glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        ASSERT_GL_NO_ERROR();

        EGLint surfaceCompontentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
        if (IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_pixel_format_float"))
        {
            eglGetConfigAttrib(mDisplay, surfaceConfig, EGL_COLOR_COMPONENT_TYPE_EXT,
                               &surfaceCompontentType);
        }

        if (surfaceCompontentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT)
        {
            EXPECT_PIXEL_EQ(250, 250, 0, 0, 255, 255);
        }
        else
        {
            EXPECT_PIXEL_32F_EQ(250, 250, 0, 0, 1.0f, 1.0f);
        }

        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        ASSERT_EGL_SUCCESS();
    }

    void testMakeCurrentFails(EGLSurface surface, EGLContext context) const
    {
        eglMakeCurrent(mDisplay, surface, surface, context);
        EXPECT_EGL_ERROR(EGL_BAD_MATCH);
    }
};

// The test is split in several subtest so that simple cases
// are tested separately. Also each surface types are not tested
// together.

// Basic test checking contexts and windows created with the
// same config can render.
class EGLContextCompatibilityTest_WindowSameConfig : public EGLContextCompatibilityTest
{
  public:
    EGLContextCompatibilityTest_WindowSameConfig(EGLint renderer, size_t configIndex)
        : EGLContextCompatibilityTest(renderer), mConfigIndex(configIndex)
    {}

    void TestBody() override
    {
        EGLConfig config = mConfigs[mConfigIndex];

        EGLint surfaceType;
        eglGetConfigAttrib(mDisplay, config, EGL_SURFACE_TYPE, &surfaceType);
        ASSERT_EGL_SUCCESS();

        ANGLE_SKIP_TEST_IF((surfaceType & EGL_WINDOW_BIT) == 0);

        testWindowCompatibility(config, config, true);
    }

    EGLint mConfigIndex;
};

// Basic test checking contexts and pbuffers created with the
// same config can render.
class EGLContextCompatibilityTest_PbufferSameConfig : public EGLContextCompatibilityTest
{
  public:
    EGLContextCompatibilityTest_PbufferSameConfig(EGLint renderer, size_t configIndex)
        : EGLContextCompatibilityTest(renderer), mConfigIndex(configIndex)
    {}

    void TestBody() override
    {
        EGLConfig config = mConfigs[mConfigIndex];

        EGLint surfaceType;
        eglGetConfigAttrib(mDisplay, config, EGL_SURFACE_TYPE, &surfaceType);
        ASSERT_EGL_SUCCESS();

        ANGLE_SKIP_TEST_IF((surfaceType & EGL_PBUFFER_BIT) == 0);

        testPbufferCompatibility(config, config, true);
    }

    EGLint mConfigIndex;
};

// Check that a context rendering to a window with a different
// config works or errors according to the EGL compatibility rules
class EGLContextCompatibilityTest_WindowDifferentConfig : public EGLContextCompatibilityTest
{
  public:
    EGLContextCompatibilityTest_WindowDifferentConfig(EGLint renderer,
                                                      size_t configIndexA,
                                                      size_t configIndexB)
        : EGLContextCompatibilityTest(renderer),
          mConfigIndexA(configIndexA),
          mConfigIndexB(configIndexB)
    {}

    void TestBody() override
    {
        EGLConfig config1 = mConfigs[mConfigIndexA];
        EGLConfig config2 = mConfigs[mConfigIndexB];

        EGLint surfaceType;
        eglGetConfigAttrib(mDisplay, config1, EGL_SURFACE_TYPE, &surfaceType);
        ASSERT_EGL_SUCCESS();

        ANGLE_SKIP_TEST_IF((surfaceType & EGL_WINDOW_BIT) == 0);

        testWindowCompatibility(config1, config2,
                                areConfigsCompatible(config1, config2, EGL_WINDOW_BIT));
    }

    EGLint mConfigIndexA;
    EGLint mConfigIndexB;
};

// Check that a context rendering to a pbuffer with a different
// config works or errors according to the EGL compatibility rules
class EGLContextCompatibilityTest_PbufferDifferentConfig : public EGLContextCompatibilityTest
{
  public:
    EGLContextCompatibilityTest_PbufferDifferentConfig(EGLint renderer,
                                                       size_t configIndexA,
                                                       size_t configIndexB)
        : EGLContextCompatibilityTest(renderer),
          mConfigIndexA(configIndexA),
          mConfigIndexB(configIndexB)
    {}

    void TestBody() override
    {
        EGLConfig config1 = mConfigs[mConfigIndexA];
        EGLConfig config2 = mConfigs[mConfigIndexB];

        EGLint surfaceType;
        eglGetConfigAttrib(mDisplay, config1, EGL_SURFACE_TYPE, &surfaceType);
        ASSERT_EGL_SUCCESS();

        ANGLE_SKIP_TEST_IF((surfaceType & EGL_PBUFFER_BIT) == 0);

        testPbufferCompatibility(config1, config2,
                                 areConfigsCompatible(config1, config2, EGL_PBUFFER_BIT));
    }

    EGLint mConfigIndexA;
    EGLint mConfigIndexB;
};
}  // namespace

void RegisterContextCompatibilityTests()
{
    // Linux failures: http://anglebug.com/42263563
    // Also wrong drivers loaded under xvfb due to egl* calls: https://anglebug.com/42266535
    // Also need to create OSWindow before eglGetPlatformDisplay to set
    //   EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE correctly to
    //   OSWindow::getNativeDisplayPlatformType().  http://anglebug.com/520829539
    if (IsLinux())
    {
        std::cerr << "EGLContextCompatibilityTest: skipped on Linux\n";
        return;
    }

    std::vector<EGLint> renderers = {{
        EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
        EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE,
        EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE,
        EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE,
        EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE,
    }};

    LoadEntryPointsWithUtilLoader(kDefaultGLESDriver);

    if (eglGetPlatformDisplay == nullptr)
    {
        std::cerr << "EGLContextCompatibilityTest: missing eglGetPlatformDisplay\n";
        return;
    }

    for (EGLint renderer : renderers)
    {
        PlatformParameters params = FromRenderer(renderer);
        if (!IsPlatformAvailable(params))
            continue;

        EGLAttrib dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, renderer, EGL_NONE};
        EGLDisplay display    = eglGetPlatformDisplay(
            GetEglPlatform(), reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
        if (display == EGL_NO_DISPLAY)
        {
            std::cerr << "EGLContextCompatibilityTest: eglGetPlatformDisplay error\n";
            return;
        }

        if (eglInitialize(display, nullptr, nullptr) != EGL_TRUE)
        {
            std::cerr << "EGLContextCompatibilityTest: eglInitialize error\n";
            return;
        }

        std::vector<EGLConfig> configs;
        std::vector<std::string> configNames;
        std::string rendererName = GetRendererName(renderer);

        {
            std::unordered_set<std::string> configNameSet;

            for (EGLConfig config : GetConfigs(display))
            {
                std::string configName = EGLConfigName(display, config);
                // Skip configs with duplicate names
                if (configNameSet.count(configName) == 0)
                {
                    configNames.push_back(configName);
                    configNameSet.insert(configName);
                    configs.push_back(config);
                }
            }
        }

        for (size_t configIndex = 0; configIndex < configs.size(); ++configIndex)
        {
            if (ShouldSkipConfig(display, configs[configIndex], true))
                continue;

            std::stringstream nameStr;
            nameStr << "WindowSameConfig/" << rendererName << "_" << configNames[configIndex];
            std::string name = nameStr.str();

            testing::RegisterTest(
                "EGLContextCompatibilityTest", name.c_str(), nullptr, nullptr, __FILE__, __LINE__,
                [renderer, configIndex]() -> EGLContextCompatibilityTest * {
                    return new EGLContextCompatibilityTest_WindowSameConfig(renderer, configIndex);
                });
        }

        for (size_t configIndex = 0; configIndex < configs.size(); ++configIndex)
        {
            if (ShouldSkipConfig(display, configs[configIndex], false))
                continue;

            std::stringstream nameStr;
            nameStr << "PbufferSameConfig/" << rendererName << "_" << configNames[configIndex];
            std::string name = nameStr.str();

            testing::RegisterTest(
                "EGLContextCompatibilityTest", name.c_str(), nullptr, nullptr, __FILE__, __LINE__,
                [renderer, configIndex]() -> EGLContextCompatibilityTest * {
                    return new EGLContextCompatibilityTest_PbufferSameConfig(renderer, configIndex);
                });
        }

        // Because there are so many permutations, we skip some configs randomly.
        // Attempt to run at most 100 tests per renderer.
        RNG rng(0);
        constexpr uint32_t kMaximumTestsPerRenderer = 100;
        const uint32_t kTestCount = static_cast<uint32_t>(configs.size() * configs.size());
        const float kSkipP =
            1.0f - (static_cast<float>(std::min(kMaximumTestsPerRenderer, kTestCount)) /
                    static_cast<float>(kTestCount));

        for (size_t configIndexA = 0; configIndexA < configs.size(); ++configIndexA)
        {
            if (ShouldSkipConfig(display, configs[configIndexA], true))
                continue;

            std::string configNameA = configNames[configIndexA];

            for (size_t configIndexB = 0; configIndexB < configs.size(); ++configIndexB)
            {
                if (ShouldSkipConfig(display, configs[configIndexB], true))
                    continue;

                if (rng.randomFloat() < kSkipP)
                    continue;

                std::string configNameB = configNames[configIndexB];

                std::stringstream nameStr;
                nameStr << "WindowDifferentConfig/" << rendererName << "_" << configNameA << "_"
                        << configNameB;
                std::string name = nameStr.str();

                testing::RegisterTest(
                    "EGLContextCompatibilityTest", name.c_str(), nullptr, nullptr, __FILE__,
                    __LINE__,
                    [renderer, configIndexA, configIndexB]() -> EGLContextCompatibilityTest * {
                        return new EGLContextCompatibilityTest_WindowDifferentConfig(
                            renderer, configIndexA, configIndexB);
                    });
            }
        }

        for (size_t configIndexA = 0; configIndexA < configs.size(); ++configIndexA)
        {
            if (ShouldSkipConfig(display, configs[configIndexA], false))
                continue;

            std::string configNameA = configNames[configIndexA];

            for (size_t configIndexB = 0; configIndexB < configs.size(); ++configIndexB)
            {
                if (ShouldSkipConfig(display, configs[configIndexB], false))
                    continue;

                if (rng.randomFloat() < kSkipP)
                    continue;

                std::string configNameB = configNames[configIndexB];

                std::stringstream nameStr;
                nameStr << "PbufferDifferentConfig/" << rendererName << "_" << configNameA << "_"
                        << configNameB;
                std::string name = nameStr.str();

                testing::RegisterTest(
                    "EGLContextCompatibilityTest", name.c_str(), nullptr, nullptr, __FILE__,
                    __LINE__,
                    [renderer, configIndexA, configIndexB]() -> EGLContextCompatibilityTest * {
                        return new EGLContextCompatibilityTest_PbufferDifferentConfig(
                            renderer, configIndexA, configIndexB);
                    });
            }
        }

        if (eglTerminate(display) == EGL_FALSE)
        {
            std::cerr << "EGLContextCompatibilityTest: eglTerminate error\n";
            return;
        }
    }
}
