1 //
2 // Copyright 2022 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // EGLWaylandTest.cpp: tests for EGL_EXT_platform_wayland
8
9 #include <gtest/gtest.h>
10
11 #include <EGL/egl.h>
12 #include <EGL/eglext.h>
13 #include <wayland-client.h>
14 #include <wayland-egl-backend.h>
15
16 #include "test_utils/ANGLETest.h"
17 #include "util/linux/wayland/WaylandWindow.h"
18
19 using namespace angle;
20
21 namespace
22 {
23 const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
24 }
25
26 class EGLWaylandTest : public ANGLETest<>
27 {
28 public:
getDisplayAttributes() const29 std::vector<EGLint> getDisplayAttributes() const
30 {
31 std::vector<EGLint> attribs;
32
33 attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
34 attribs.push_back(GetParam().getRenderer());
35 attribs.push_back(EGL_NONE);
36
37 return attribs;
38 }
39
testSetUp()40 void testSetUp() override
41 {
42 mOsWindow = WaylandWindow::New();
43 ASSERT_TRUE(mOsWindow->initialize("EGLWaylandTest", 500, 500));
44 setWindowVisible(mOsWindow, true);
45
46 EGLNativeDisplayType waylandDisplay = mOsWindow->getNativeDisplay();
47 std::vector<EGLint> attribs = getDisplayAttributes();
48 mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, (void *)waylandDisplay,
49 attribs.data());
50 ASSERT_NE(EGL_NO_DISPLAY, mDisplay);
51
52 ASSERT_TRUE(EGL_TRUE == eglInitialize(mDisplay, nullptr, nullptr));
53
54 int nConfigs = 0;
55 ASSERT_TRUE(EGL_TRUE == eglGetConfigs(mDisplay, nullptr, 0, &nConfigs));
56 ASSERT_GE(nConfigs, 1);
57
58 int nReturnedConfigs = 0;
59 mConfigs.resize(nConfigs);
60 ASSERT_TRUE(EGL_TRUE ==
61 eglGetConfigs(mDisplay, mConfigs.data(), nConfigs, &nReturnedConfigs));
62 ASSERT_EQ(nConfigs, nReturnedConfigs);
63 }
64
testTearDown()65 void testTearDown() override
66 {
67 mConfigs.clear();
68 eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
69 eglTerminate(mDisplay);
70 OSWindow::Delete(&mOsWindow);
71 }
72
73 OSWindow *mOsWindow;
74 EGLDisplay mDisplay;
75 std::vector<EGLConfig> mConfigs;
76 };
77
78 // Test that a Wayland window can be created and used for rendering
TEST_P(EGLWaylandTest,WaylandWindowRendering)79 TEST_P(EGLWaylandTest, WaylandWindowRendering)
80 {
81 for (EGLConfig config : mConfigs)
82 {
83 // Finally, try to do a clear on the window.
84 EGLContext context = eglCreateContext(mDisplay, config, EGL_NO_CONTEXT, contextAttribs);
85 ASSERT_NE(EGL_NO_CONTEXT, context);
86
87 EGLSurface window =
88 eglCreateWindowSurface(mDisplay, config, mOsWindow->getNativeWindow(), nullptr);
89 ASSERT_EGL_SUCCESS();
90
91 eglMakeCurrent(mDisplay, window, window, context);
92 ASSERT_EGL_SUCCESS();
93
94 glViewport(0, 0, 500, 500);
95 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
96 glClear(GL_COLOR_BUFFER_BIT);
97 ASSERT_GL_NO_ERROR();
98 EXPECT_PIXEL_EQ(250, 250, 0, 0, 255, 255);
99
100 // Teardown
101 eglDestroySurface(mDisplay, window);
102 ASSERT_EGL_SUCCESS();
103
104 eglDestroyContext(mDisplay, context);
105 ASSERT_EGL_SUCCESS();
106
107 eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
108 ASSERT_EGL_SUCCESS();
109 }
110 }
111
112 // Test that a Wayland window can swap buffers multiple times with no issues
TEST_P(EGLWaylandTest,SwapBuffers)113 TEST_P(EGLWaylandTest, SwapBuffers)
114 {
115 for (EGLConfig config : mConfigs)
116 {
117 EGLContext context = eglCreateContext(mDisplay, config, EGL_NO_CONTEXT, contextAttribs);
118 ASSERT_NE(EGL_NO_CONTEXT, context);
119
120 EGLSurface surface =
121 eglCreateWindowSurface(mDisplay, config, mOsWindow->getNativeWindow(), nullptr);
122 ASSERT_EGL_SUCCESS();
123
124 eglMakeCurrent(mDisplay, surface, surface, context);
125 ASSERT_EGL_SUCCESS();
126
127 const uint32_t loopcount = 16;
128 for (uint32_t i = 0; i < loopcount; i++)
129 {
130 mOsWindow->messageLoop();
131
132 glViewport(0, 0, 500, 500);
133 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
134 glClear(GL_COLOR_BUFFER_BIT);
135 ASSERT_GL_NO_ERROR() << "glClear failed";
136 EXPECT_PIXEL_EQ(250, 250, 0, 0, 255, 255);
137
138 eglSwapBuffers(mDisplay, surface);
139 ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
140 }
141
142 // Teardown
143 eglDestroySurface(mDisplay, surface);
144 ASSERT_EGL_SUCCESS();
145
146 eglDestroyContext(mDisplay, context);
147 ASSERT_EGL_SUCCESS();
148
149 eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
150 ASSERT_EGL_SUCCESS();
151 }
152 }
153
154 ANGLE_INSTANTIATE_TEST(EGLWaylandTest, WithNoFixture(ES2_VULKAN()));
155