70640bbbdd341c8eea9dea11c52aa122c996ad22
[platform/upstream/VK-GL-CTS.git] / framework / platform / wayland / tcuWayland.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program Tester Core
3  * ----------------------------------------
4  *
5  * Copyright (c) 2014 The Android Open Source Project
6  * Copyright (c) 2016 The Khronos Group Inc.
7  * Copyright (c) 2016 Mun Gwan-gyeong <elongbug@gmail.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief wayland utilities.
24  *//*--------------------------------------------------------------------*/
25
26 #include "tcuWayland.hpp"
27 #include "gluRenderConfig.hpp"
28 #include "deMemory.h"
29
30 #include <stdio.h>
31
32 namespace tcu
33 {
34 namespace wayland
35 {
36
37 enum
38 {
39         DEFAULT_WINDOW_WIDTH    = 400,
40         DEFAULT_WINDOW_HEIGHT   = 300
41 };
42
43 EventState::EventState (void)
44         : m_quit(false)
45 {
46 }
47
48 EventState::~EventState (void)
49 {
50 }
51
52 void EventState::setQuitFlag (bool quit)
53 {
54         de::ScopedLock lock(m_mutex);
55         m_quit = quit;
56 }
57
58 bool EventState::getQuitFlag (void)
59 {
60         de::ScopedLock lock(m_mutex);
61         return m_quit;
62 }
63 const struct wl_registry_listener Display::s_registryListener =
64 {
65         Display::handleGlobal,
66         Display::handleGlobalRemove
67 };
68
69 const struct wl_shell_surface_listener Window::s_shellSurfaceListener =
70 {
71         Window::handlePing,
72         Window::handleConfigure,
73         Window::handlePopupDone,
74 };
75
76 void Display::handleGlobal (void* data, struct wl_registry* registry, uint32_t id, const char* interface, uint32_t version)
77 {
78         Display* _this = static_cast<Display*>(data);
79         DE_UNREF(version);
80
81         if (!strcmp(interface, "wl_compositor"))
82                 _this->m_compositor = static_cast<struct wl_compositor*>(wl_registry_bind(registry, id, &wl_compositor_interface, 3));
83         /* Todo: when the xdg_shell protocol has stablized, we should move wl_shell to xdg_shell. */
84         if (!strcmp(interface, "wl_shell"))
85                 _this->m_shell = static_cast<struct wl_shell*>(wl_registry_bind(registry, id, &wl_shell_interface, 1));
86 }
87
88 void Display::handleGlobalRemove (void* data, struct wl_registry* registry, uint32_t name)
89 {
90         DE_UNREF(data);
91         DE_UNREF(registry);
92         DE_UNREF(name);
93 }
94
95 Display::Display (EventState& eventState, const char* name)
96         : m_eventState  (eventState)
97         , m_display             (DE_NULL)
98 {
99         try
100         {
101                 m_display = wl_display_connect(name);
102                 if (!m_display)
103                         throw ResourceError("Failed to open display", name, __FILE__, __LINE__);
104
105                 m_registry = wl_display_get_registry(m_display);
106                 if (!m_registry)
107                         throw ResourceError("Failed to get registry", name, __FILE__, __LINE__);
108
109                 wl_registry_add_listener(m_registry, &s_registryListener, this);
110                 wl_display_roundtrip(m_display);
111                 if (!m_compositor)
112                         throw ResourceError("Failed to bind compositor", name, __FILE__, __LINE__);
113                 if (!m_shell)
114                         throw ResourceError("Failed to bind shell", name, __FILE__, __LINE__);
115         }
116         catch (...)
117         {
118                 if (m_shell)
119                         wl_shell_destroy(m_shell);
120
121                 if (m_compositor)
122                         wl_compositor_destroy(m_compositor);
123
124                 if (m_registry)
125                         wl_registry_destroy(m_registry);
126
127                 if (m_display)
128                         wl_display_disconnect(m_display);
129
130                 throw;
131         }
132 }
133
134 Display::~Display (void)
135 {
136         if (m_shell)
137                 wl_shell_destroy(m_shell);
138
139         if (m_compositor)
140                 wl_compositor_destroy(m_compositor);
141
142         if (m_registry)
143                 wl_registry_destroy(m_registry);
144
145         if (m_display)
146                 wl_display_disconnect(m_display);
147 }
148
149 void Display::processEvents (void)
150 {
151 }
152
153 Window::Window (Display& display, int width, int height)
154         : m_display             (display)
155 {
156         try
157         {
158                 m_surface = wl_compositor_create_surface(display.getCompositor());
159                 if (!m_surface)
160                         throw ResourceError("Failed to create ", "surface", __FILE__, __LINE__);
161
162                 m_shellSurface = wl_shell_get_shell_surface(display.getShell(), m_surface);
163                 if (!m_shellSurface)
164                         throw ResourceError("Failed to create ", "shell_surface", __FILE__, __LINE__);
165
166                 wl_shell_surface_add_listener(m_shellSurface, &s_shellSurfaceListener, this);
167                 wl_shell_surface_set_title(m_shellSurface, "CTS for OpenGL (ES)");
168                 wl_shell_surface_set_toplevel(m_shellSurface);
169
170                 if (width == glu::RenderConfig::DONT_CARE)
171                         width = DEFAULT_WINDOW_WIDTH;
172                 if (height == glu::RenderConfig::DONT_CARE)
173                         height = DEFAULT_WINDOW_HEIGHT;
174
175                 m_window = wl_egl_window_create(m_surface, width, height);
176                 if (!m_window)
177                         throw ResourceError("Failed to create ", "window", __FILE__, __LINE__);
178         }
179         catch (...)
180         {
181                 throw;
182         }
183         TCU_CHECK(m_window);
184 }
185
186 void Window::setVisibility (bool visible)
187 {
188         m_visible = visible;
189 }
190
191 void Window::getDimensions (int* width, int* height) const
192 {
193         wl_egl_window_get_attached_size(m_window, width, height);
194 }
195
196 void Window::setDimensions (int width, int height)
197 {
198         wl_egl_window_resize(m_window, width, height, 0, 0);
199 }
200
201 void Window::processEvents (void)
202 {
203 }
204
205 void Window::handlePing (void* data, struct wl_shell_surface* shellSurface, uint32_t serial)
206 {
207         DE_UNREF(data);
208         wl_shell_surface_pong(shellSurface, serial);
209 }
210
211 void Window::handleConfigure (void* data, struct wl_shell_surface* shellSurface, uint32_t edges, int32_t width, int32_t height)
212 {
213         DE_UNREF(data);
214         DE_UNREF(shellSurface);
215         DE_UNREF(edges);
216         DE_UNREF(width);
217         DE_UNREF(height);
218 }
219
220 void Window::handlePopupDone (void* data, struct wl_shell_surface* shellSurface)
221 {
222         DE_UNREF(data);
223         DE_UNREF(shellSurface);
224 }
225
226 Window::~Window (void)
227 {
228         if (m_window)
229                 wl_egl_window_destroy(m_window);
230         if (m_shellSurface)
231                 wl_shell_surface_destroy(m_shellSurface);
232         if (m_surface)
233                 wl_surface_destroy(m_surface);
234 }
235
236 } // wayland
237 } // tcu