//
// 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.
//
// Only run the EGLContextCompatibilityTest on release builds.  The execution time of this test
// scales with the square of the number of configs exposed and can time out in some debug builds.
// http://anglebug.com/2121

#include <gtest/gtest.h>

#include <vector>

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

using namespace angle;

namespace
{

const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
}

class EGLContextCompatibilityTest : public ANGLETest
{
  public:
    EGLContextCompatibilityTest() : mDisplay(0) {}

    void testSetUp() override
    {
        ASSERT_TRUE(eglGetPlatformDisplayEXT != nullptr);

        EGLint dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(), EGL_NONE};
        mDisplay           = eglGetPlatformDisplayEXT(
            EGL_PLATFORM_ANGLE_ANGLE, 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 testTearDown() override
    {
        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        eglTerminate(mDisplay);
    }

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

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

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

    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);
        osWindow->setVisible(true);

        EGLContext context =
            eglCreateContext(mDisplay, contextConfig, EGL_NO_CONTEXT, contextAttribs);
        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, contextAttribs);
        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;

  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.
TEST_P(EGLContextCompatibilityTest, WindowSameConfig)
{
    ANGLE_SKIP_TEST_IF(IsDebug());  // http://anglebug.com/2121

    for (size_t i = 0; i < mConfigs.size(); i++)
    {
        EGLConfig config = mConfigs[i];

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

        if ((surfaceType & EGL_WINDOW_BIT) != 0)
        {
            // Disabling multisampled configurations due to test instability with various graphics
            // cards, and RGBA16F/RGB10_A2 on Android due to OSWindow on Android not providing
            // compatible windows (anglebug.com/3156)
            if (isMultisampledConfig(config) ||
                (IsAndroid() && (isRGB10_A2Config(config) || isRGBA16FConfig(config))))
            {
                continue;
            }
            testWindowCompatibility(config, config, true);
        }
    }
}

// Basic test checking contexts and pbuffers created with the
// same config can render.
TEST_P(EGLContextCompatibilityTest, PbufferSameConfig)
{
    ANGLE_SKIP_TEST_IF(IsDebug());  // http://anglebug.com/2121

    for (size_t i = 0; i < mConfigs.size(); i++)
    {
        EGLConfig config = mConfigs[i];

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

        if ((surfaceType & EGL_PBUFFER_BIT) != 0)
        {
            // Disabling multisampled configurations due to test instability with various graphics
            // cards, and RGB10_A2 on Android due to OSWindow on Android not providing compatible
            // windows (anglebug.com/3156)
            if (isMultisampledConfig(config) || (IsAndroid() && isRGB10_A2Config(config)))
            {
                continue;
            }
            testPbufferCompatibility(config, config, true);
        }
    }
}

// Check that a context rendering to a window with a different
// config works or errors according to the EGL compatibility rules
TEST_P(EGLContextCompatibilityTest, WindowDifferentConfig)
{
    ANGLE_SKIP_TEST_IF(IsDebug());  // http://anglebug.com/2121

    // anglebug.com/2183
    // Actually failed only on (IsIntel() && IsWindows() && IsD3D11()),
    // but it's impossible to do other tests since GL_RENDERER is NULL
    ANGLE_SKIP_TEST_IF(IsWindows());

    for (size_t i = 0; i < mConfigs.size(); i++)
    {
        EGLConfig config1 = mConfigs[i];
        // Disabling multisampled configurations due to test instability with various graphics
        // cards, and RGBA16F/RGB10_A2 on Android due to OSWindow on Android not providing
        // compatible windows (anglebug.com/3156)
        if (isMultisampledConfig(config1) ||
            (IsAndroid() && (isRGB10_A2Config(config1) || isRGBA16FConfig(config1))))
        {
            continue;
        }

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

        if ((surfaceType & EGL_WINDOW_BIT) == 0)
        {
            continue;
        }

        for (size_t j = 0; j < mConfigs.size(); j++)
        {
            EGLConfig config2 = mConfigs[j];
            // Disabling multisampled configurations due to test instability with various graphics
            // cards, and RGBA16F/RGB10_A2 on Android due to OSWindow on Android not providing
            // compatible windows (anglebug.com/3156)
            if (isMultisampledConfig(config2) ||
                (IsAndroid() && (isRGB10_A2Config(config2) || isRGBA16FConfig(config2))))
            {
                continue;
            }
            testWindowCompatibility(config1, config2,
                                    areConfigsCompatible(config1, config2, EGL_WINDOW_BIT));
        }
    }
}

// Check that a context rendering to a pbuffer with a different
// config works or errors according to the EGL compatibility rules
TEST_P(EGLContextCompatibilityTest, PbufferDifferentConfig)
{
    ANGLE_SKIP_TEST_IF(IsDebug());  // http://anglebug.com/2121

    for (size_t i = 0; i < mConfigs.size(); i++)
    {
        EGLConfig config1 = mConfigs[i];
        // Disabling multisampled configurations due to test instability with various graphics
        // cards, and RGB10_A2 on Android due to OSWindow on Android not providing compatible
        // windows (anglebug.com/3156)
        if (isMultisampledConfig(config1) || (IsAndroid() && isRGB10_A2Config(config1)))
        {
            continue;
        }

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

        if ((surfaceType & EGL_PBUFFER_BIT) == 0)
        {
            continue;
        }

        for (size_t j = 0; j < mConfigs.size(); j++)
        {
            EGLConfig config2 = mConfigs[j];
            // Disabling multisampled configurations due to test instability with various graphics
            // cards, and RGB10_A2 on Android due to OSWindow on Android not providing compatible
            // windows (anglebug.com/3156)
            if (isMultisampledConfig(config2) || (IsAndroid() && isRGB10_A2Config(config2)))
            {
                continue;
            }
            testPbufferCompatibility(config1, config2,
                                     areConfigsCompatible(config1, config2, EGL_PBUFFER_BIT));
        }
    }
}

ANGLE_INSTANTIATE_TEST(EGLContextCompatibilityTest,
                       WithNoFixture(ES2_D3D9()),
                       WithNoFixture(ES2_D3D11()),
                       WithNoFixture(ES2_OPENGL()),
                       WithNoFixture(ES2_OPENGLES()),
                       WithNoFixture(ES2_VULKAN()));
