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

// EGLX11VisualTest.cpp: tests for EGL_ANGLE_x11_visual extension

#include <gtest/gtest.h>

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <X11/Xlib.h>

#include "test_utils/ANGLETest.h"
#include "util/OSWindow.h"
#include "util/x11/X11Window.h"

using namespace angle;

namespace
{

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

class EGLX11VisualHintTest : public ANGLETest
{
  public:
    void testSetUp() override { mDisplay = XOpenDisplay(nullptr); }

    std::vector<EGLint> getDisplayAttributes(int visualId) const
    {
        std::vector<EGLint> attribs;

        attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
        attribs.push_back(GetParam().getRenderer());
        attribs.push_back(EGL_X11_VISUAL_ID_ANGLE);
        attribs.push_back(visualId);
        attribs.push_back(EGL_NONE);

        return attribs;
    }

    unsigned int chooseDifferentVisual(unsigned int visualId)
    {
        int numVisuals;
        XVisualInfo visualTemplate;
        visualTemplate.screen = DefaultScreen(mDisplay);

        XVisualInfo *visuals =
            XGetVisualInfo(mDisplay, VisualScreenMask, &visualTemplate, &numVisuals);
        EXPECT_TRUE(numVisuals >= 2);

        for (int i = 0; i < numVisuals; ++i)
        {
            if (visuals[i].visualid != visualId)
            {
                int result = visuals[i].visualid;
                XFree(visuals);
                return result;
            }
        }

        EXPECT_TRUE(false);
        return -1;
    }

  protected:
    Display *mDisplay;
};

// Test that display creation fails if the visual ID passed in invalid.
TEST_P(EGLX11VisualHintTest, InvalidVisualID)
{
    static const int gInvalidVisualId = -1;
    auto attributes                   = getDisplayAttributes(gInvalidVisualId);

    EGLDisplay display =
        eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, attributes.data());
    ASSERT_TRUE(display != EGL_NO_DISPLAY);

    ASSERT_TRUE(EGL_FALSE == eglInitialize(display, nullptr, nullptr));
    ASSERT_EGL_ERROR(EGL_NOT_INITIALIZED);
}

// Test that context creation with a visual ID succeeds, that the context exposes
// only one config, and that a clear on a surface with this config works.
TEST_P(EGLX11VisualHintTest, ValidVisualIDAndClear)
{
    // We'll test the extension with one visual ID but we don't care which one. This means we
    // can use OSWindow to create a window and just grab its visual.
    OSWindow *osWindow = OSWindow::New();
    osWindow->initialize("EGLX11VisualHintTest", 500, 500);
    osWindow->setVisible(true);

    Window xWindow = osWindow->getNativeWindow();

    XWindowAttributes windowAttributes;
    ASSERT_NE(0, XGetWindowAttributes(mDisplay, xWindow, &windowAttributes));
    int visualId = windowAttributes.visual->visualid;

    auto attributes = getDisplayAttributes(visualId);
    EGLDisplay display =
        eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, attributes.data());
    ASSERT_NE(EGL_NO_DISPLAY, display);

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

    // While this is not required by the extension, test that our implementation returns only one
    // config, with the same native visual Id that we provided.
    int nConfigs = 0;
    ASSERT_TRUE(EGL_TRUE == eglGetConfigs(display, nullptr, 0, &nConfigs));
    ASSERT_EQ(1, nConfigs);

    int nReturnedConfigs = 0;
    EGLConfig config;
    ASSERT_TRUE(EGL_TRUE == eglGetConfigs(display, &config, 1, &nReturnedConfigs));
    ASSERT_EQ(nConfigs, nReturnedConfigs);

    EGLint eglNativeId;
    ASSERT_TRUE(EGL_TRUE ==
                eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &eglNativeId));
    ASSERT_EQ(visualId, eglNativeId);

    // Finally, try to do a clear on the window.
    EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
    ASSERT_NE(EGL_NO_CONTEXT, context);

    EGLSurface window = eglCreateWindowSurface(display, config, xWindow, nullptr);
    ASSERT_EGL_SUCCESS();

    eglMakeCurrent(display, window, window, 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();
    EXPECT_PIXEL_EQ(250, 250, 0, 0, 255, 255);

    // Teardown
    eglDestroySurface(display, window);
    ASSERT_EGL_SUCCESS();

    eglDestroyContext(display, context);
    ASSERT_EGL_SUCCESS();

    OSWindow::Delete(&osWindow);

    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    eglTerminate(display);
}

// Test that EGL_BAD_MATCH is generated when trying to create an EGL window from
// an X11 window whose visual ID doesn't match the visual ID passed at display creation.
TEST_P(EGLX11VisualHintTest, InvalidWindowVisualID)
{
    // Get the default visual ID, as a good guess of a visual id for which display
    // creation will succeed.
    int visualId;
    {
        OSWindow *osWindow = OSWindow::New();
        osWindow->initialize("EGLX11VisualHintTest", 500, 500);
        osWindow->setVisible(true);

        Window xWindow = osWindow->getNativeWindow();

        XWindowAttributes windowAttributes;
        ASSERT_NE(0, XGetWindowAttributes(mDisplay, xWindow, &windowAttributes));
        visualId = windowAttributes.visual->visualid;

        OSWindow::Delete(&osWindow);
    }

    auto attributes = getDisplayAttributes(visualId);
    EGLDisplay display =
        eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, attributes.data());
    ASSERT_NE(EGL_NO_DISPLAY, display);

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

    // Initialize the window with a visual id different from the display's visual id
    int otherVisualId = chooseDifferentVisual(visualId);
    ASSERT_NE(visualId, otherVisualId);

    OSWindow *osWindow = new X11Window(otherVisualId);
    osWindow->initialize("EGLX11VisualHintTest", 500, 500);
    osWindow->setVisible(true);

    Window xWindow = osWindow->getNativeWindow();

    // Creating the EGL window should fail with EGL_BAD_MATCH
    int nReturnedConfigs = 0;
    EGLConfig config;
    ASSERT_TRUE(EGL_TRUE == eglGetConfigs(display, &config, 1, &nReturnedConfigs));
    ASSERT_EQ(1, nReturnedConfigs);

    EGLSurface window = eglCreateWindowSurface(display, config, xWindow, nullptr);
    ASSERT_EQ(EGL_NO_SURFACE, window);
    ASSERT_EGL_ERROR(EGL_BAD_MATCH);

    OSWindow::Delete(&osWindow);
}

ANGLE_INSTANTIATE_TEST(EGLX11VisualHintTest, WithNoFixture(ES2_OPENGL()));
