21 #define VK_USE_PLATFORM_WAYLAND_KHR 22 #include "wayland.hpp" 27 #include <sys/types.h> 34 Platform &Platform::get()
38 static WaylandPlatform singleton;
42 VkSurfaceKHR WaylandPlatform::createSurface()
44 if (FAILED(initWindow()))
45 return VK_NULL_HANDLE;
48 PFN_vkCreateWaylandSurfaceKHR fpCreateWaylandSurfaceKHR;
49 if (!VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_SYMBOL(instance,
"vkCreateWaylandSurfaceKHR", fpCreateWaylandSurfaceKHR))
50 return VK_NULL_HANDLE;
52 VkWaylandSurfaceCreateInfoKHR info = { VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR };
53 info.display = waylandData.dpy;
54 info.surface = waylandData.surf;
56 VK_CHECK(fpCreateWaylandSurfaceKHR(instance, &info,
nullptr, &surface));
60 WaylandPlatform::WaylandPlatform()
62 memset(&waylandData, 0,
sizeof(waylandData));
67 static void registryHandleGlobal(
void *data, wl_registry *reg, uint32_t
id,
const char *interface, uint32_t)
69 WaylandData *waylandData =
static_cast<WaylandData *
>(data);
70 if (!strcmp(interface,
"wl_compositor"))
71 waylandData->compositor = static_cast<wl_compositor *>(wl_registry_bind(reg,
id, &wl_compositor_interface, 1));
72 else if (!strcmp(interface,
"wl_shell"))
73 waylandData->shell = static_cast<wl_shell *>(wl_registry_bind(reg,
id, &wl_shell_interface, 1));
76 static void registryHandleGlobalRemove(
void *, wl_registry *, uint32_t)
80 static const wl_registry_listener registryListener = {
81 registryHandleGlobal, registryHandleGlobalRemove,
84 static void shellSurfaceHandlePing(
void *, wl_shell_surface *shellSurface, uint32_t serial)
86 wl_shell_surface_pong(shellSurface, serial);
89 static void shellSurfaceHandlePopupDone(
void *, wl_shell_surface *)
93 static void shellSurfaceHandleConfigure(
void *, wl_shell_surface *, uint32_t, int32_t width, int32_t height)
95 LOGI(
"Wayland: Surface size: %d x %d.\n", width, height);
98 static const wl_shell_surface_listener shellSurfaceListener = {
99 shellSurfaceHandlePing, shellSurfaceHandleConfigure, shellSurfaceHandlePopupDone,
104 return waylandData.status;
107 void WaylandPlatform::flushWaylandFd()
110 wl_display_dispatch_pending(waylandData.dpy);
111 wl_display_flush(waylandData.dpy);
113 fd.fd = waylandData.fd;
114 fd.events = POLLIN | POLLOUT | POLLERR | POLLHUP;
116 if (poll(&fd, 1, 0) > 0)
118 if (fd.revents & (POLLERR | POLLHUP))
120 close(waylandData.fd);
122 waylandData.status = STATUS_TEARDOWN;
125 if (fd.revents & POLLIN)
126 wl_display_dispatch(waylandData.dpy);
127 if (fd.revents & POLLOUT)
128 wl_display_flush(waylandData.dpy);
132 Result WaylandPlatform::initialize()
134 waylandData.dpy = wl_display_connect(
nullptr);
135 if (!waylandData.dpy)
136 return RESULT_ERROR_IO;
138 waylandData.registry = wl_display_get_registry(waylandData.dpy);
139 wl_registry_add_listener(waylandData.registry, ®istryListener, &waylandData);
140 wl_display_roundtrip(waylandData.dpy);
142 if (!waylandData.compositor || !waylandData.shell)
143 return RESULT_ERROR_GENERIC;
145 waylandData.fd = wl_display_get_fd(waylandData.dpy);
146 if (waylandData.fd < 0)
147 return RESULT_ERROR_IO;
149 waylandData.status = STATUS_RUNNING;
151 return WSIPlatform::initialize();
160 Result WaylandPlatform::initWindow()
162 waylandData.surf = wl_compositor_create_surface(waylandData.compositor);
163 waylandData.shellSurf = wl_shell_get_shell_surface(waylandData.shell, waylandData.surf);
165 if (!waylandData.surf || !waylandData.shellSurf)
166 return RESULT_ERROR_GENERIC;
168 wl_shell_surface_add_listener(waylandData.shellSurf, &shellSurfaceListener, &waylandData);
169 wl_shell_surface_set_toplevel(waylandData.shellSurf);
170 wl_shell_surface_set_class(waylandData.shellSurf,
"Mali SDK");
171 wl_shell_surface_set_title(waylandData.shellSurf,
"Mali SDK");
174 return RESULT_SUCCESS;
179 if (!waylandData.dpy)
180 return RESULT_ERROR_GENERIC;
182 return initVulkan(swapchain, {
"VK_KHR_surface",
"VK_KHR_wayland_surface" }, {
"VK_KHR_swapchain" });
185 void WaylandPlatform::terminate()
188 WSIPlatform::terminate();
192 if (waylandData.fd >= 0)
193 close(waylandData.fd);
195 if (waylandData.shellSurf)
196 wl_shell_surface_destroy(waylandData.shellSurf);
197 if (waylandData.surf)
198 wl_surface_destroy(waylandData.surf);
199 if (waylandData.compositor)
200 wl_compositor_destroy(waylandData.compositor);
201 if (waylandData.registry)
202 wl_registry_destroy(waylandData.registry);
204 wl_display_disconnect(waylandData.dpy);
206 waylandData.dpy =
nullptr;
210 WaylandPlatform::~WaylandPlatform()
215 Result WaylandPlatform::presentImage(
unsigned index)
217 Result res = WSIPlatform::presentImage(index);