diff options
Diffstat (limited to 'gfx/angle/src/tests/egl_tests/EGLX11VisualTest.cpp')
-rwxr-xr-x | gfx/angle/src/tests/egl_tests/EGLX11VisualTest.cpp | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/gfx/angle/src/tests/egl_tests/EGLX11VisualTest.cpp b/gfx/angle/src/tests/egl_tests/EGLX11VisualTest.cpp new file mode 100755 index 000000000..4d5179964 --- /dev/null +++ b/gfx/angle/src/tests/egl_tests/EGLX11VisualTest.cpp @@ -0,0 +1,216 @@ +// +// Copyright (c) 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 "OSWindow.h" +#include "test_utils/ANGLETest.h" +#include "x11/X11Window.h" + +using namespace angle; + +namespace +{ + +const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; +} + +class EGLX11VisualHintTest : public ::testing::TestWithParam<angle::PlatformParameters> +{ + public: + void SetUp() override + { + mEglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>( + eglGetProcAddress("eglGetPlatformDisplayEXT")); + + mDisplay = XOpenDisplay(NULL); + } + + 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; + } + } + + UNREACHABLE(); + return -1; + } + + protected: + PFNEGLGETPLATFORMDISPLAYEXTPROC mEglGetPlatformDisplayEXT; + Display *mDisplay; +}; + +// Test that display creation fails if the visual ID passed in invalid. +TEST_P(EGLX11VisualHintTest, InvalidVisualID) +{ + // The test platform will log an error in this negative test. + IgnoreANGLEPlatformMessages(); + + static const int gInvalidVisualId = -1; + auto attributes = getDisplayAttributes(gInvalidVisualId); + + EGLDisplay display = + mEglGetPlatformDisplayEXT(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 = CreateOSWindow(); + 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 = + mEglGetPlatformDisplayEXT(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(); + + SafeDelete(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 = CreateOSWindow(); + 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; + + SafeDelete(osWindow); + } + + auto attributes = getDisplayAttributes(visualId); + EGLDisplay display = + mEglGetPlatformDisplayEXT(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); + + SafeDelete(osWindow); +} + +ANGLE_INSTANTIATE_TEST(EGLX11VisualHintTest, ES2_OPENGL()); |