Fix hang on startup under Wayland & LIBDECOR with the VULKAN backend
Create a dummy buffer so LIBDECOR initializes the window configuration.
This commit is contained in:
@@ -2086,6 +2086,13 @@ static int memfd_create_sealed(const char *name)
|
||||
#endif /* !HAVE_MEMFD_CREATE */
|
||||
}
|
||||
|
||||
#if defined(WITH_GHOST_WAYLAND_LIBDECOR) && defined(WITH_VULKAN_BACKEND)
|
||||
int memfd_create_sealed_for_vulkan_hack(const char *name)
|
||||
{
|
||||
return memfd_create_sealed(name);
|
||||
}
|
||||
#endif
|
||||
|
||||
enum {
|
||||
GWL_IOR_READ = 1 << 0,
|
||||
GWL_IOR_WRITE = 1 << 1,
|
||||
|
||||
@@ -88,6 +88,13 @@ bool ghost_wl_dynload_libraries_init();
|
||||
void ghost_wl_dynload_libraries_exit();
|
||||
#endif
|
||||
|
||||
#if defined(WITH_GHOST_WAYLAND_LIBDECOR) && defined(WITH_VULKAN_BACKEND)
|
||||
/**
|
||||
* Needed for temporary buffer creation.
|
||||
*/
|
||||
int memfd_create_sealed_for_vulkan_hack(const char *name);
|
||||
#endif
|
||||
|
||||
struct GWL_Output {
|
||||
|
||||
/** Wayland core types. */
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
# include <wayland_dynload_libdecor.h>
|
||||
# endif
|
||||
# include <libdecor.h>
|
||||
|
||||
# ifdef WITH_VULKAN_BACKEND
|
||||
# include <unistd.h> /* For `ftruncate`. */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Generated by `wayland-scanner`. */
|
||||
@@ -1769,11 +1773,47 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
|
||||
|
||||
/* NOTE: LIBDECOR requires the window to be created & configured before the state can be set.
|
||||
* Workaround this by using the underlying `xdg_toplevel` */
|
||||
|
||||
# ifdef WITH_VULKAN_BACKEND
|
||||
/* A dummy buffer is needed for VULKAN & LIBDECOR,
|
||||
* otherwise `decor.initial_configure_seen` and startup locks up. */
|
||||
wl_buffer *dummy_buffer = nullptr;
|
||||
if (window_->ghost_context_type == GHOST_kDrawingContextTypeVulkan) {
|
||||
const uint32_t format = WL_SHM_FORMAT_ARGB8888;
|
||||
const int format_size = 4;
|
||||
const int buffer_size = (window_->frame.size[0] * window_->frame.size[1]) * format_size;
|
||||
const int fd = memfd_create_sealed_for_vulkan_hack("ghost-wl-dummy-buffer");
|
||||
ftruncate(fd, buffer_size);
|
||||
wl_shm *shm = system_->wl_shm_get();
|
||||
wl_shm_pool *pool = wl_shm_create_pool(shm, fd, buffer_size);
|
||||
dummy_buffer = wl_shm_pool_create_buffer(pool,
|
||||
0,
|
||||
window_->frame.size[0],
|
||||
window_->frame.size[1],
|
||||
window_->frame.size[0] * format_size,
|
||||
format);
|
||||
wl_shm_pool_destroy(pool);
|
||||
|
||||
wl_surface_attach(window_->wl.surface, dummy_buffer, 0, 0);
|
||||
wl_surface_damage(window_->wl.surface, 0, 0, window_->frame.size[0], window_->frame.size[1]);
|
||||
wl_surface_commit(window_->wl.surface);
|
||||
::close(fd);
|
||||
}
|
||||
# endif /* WITH_GHOST_WAYLAND_LIBDECOR */
|
||||
|
||||
while (!decor.initial_configure_seen) {
|
||||
wl_display_flush(system->wl_display_get());
|
||||
wl_display_dispatch(system->wl_display_get());
|
||||
}
|
||||
|
||||
# ifdef WITH_VULKAN_BACKEND
|
||||
if (window_->ghost_context_type == GHOST_kDrawingContextTypeVulkan) {
|
||||
wl_surface_attach(window_->wl.surface, nullptr, 0, 0);
|
||||
wl_surface_commit(window_->wl.surface);
|
||||
wl_buffer_destroy(dummy_buffer);
|
||||
}
|
||||
# endif /* WITH_GHOST_WAYLAND_LIBDECOR */
|
||||
|
||||
xdg_toplevel *toplevel = libdecor_frame_get_xdg_toplevel(decor.frame);
|
||||
gwl_window_state_set_for_xdg(toplevel, state, gwl_window_state_get(window_));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user