xref: /aosp_15_r20/external/angle/src/tests/egl_tests/EGLWaylandTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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