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);