Skip to content

Commit

Permalink
wayland_vk: use FIFO if commit-timing and fifo protocols are available
Browse files Browse the repository at this point in the history
A very long time annoyance with wayland was compositors indefinitely
blocking our vo thread if the surface gets occluded in some way. We've
worked around this by using mailbox and our own custom vsync function.
Thankfully it looks like people are finally solving this and with these
two protocols it should be possible to guarantee forward progress on
vulkan which means all the workarounds we do shouldn't be needed. So we
can just request fifo in this case as a default since all we want is
standard vsync blocking.
  • Loading branch information
Dudemanguy committed Oct 12, 2024
1 parent ee00446 commit e84aa5e
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 9 deletions.
7 changes: 6 additions & 1 deletion video/out/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ protocols = [[wl_protocol_dir, 'stable/presentation-time/presentation-time.xml']
wl_protocols_source = []
wl_protocols_headers = []

foreach v: ['1.32']
foreach v: ['1.32', '1.38']
features += {'wayland-protocols-' + v.replace('.', '-'):
wayland['deps'][2].version().version_compare('>=' + v)}
endforeach
Expand All @@ -21,6 +21,11 @@ if features['wayland-protocols-1-32']
[wl_protocol_dir, 'unstable/tablet/tablet-unstable-v2.xml']] # required by cursor-shape
endif

if features['wayland-protocols-1-38']
protocols += [[wl_protocol_dir, 'staging/commit-timing/commit-timing-v1.xml'],
[wl_protocol_dir, 'staging/fifo/fifo-v1.xml']]
endif

foreach p: protocols
xml = join_paths(p)
wl_protocols_source += custom_target(xml.underscorify() + '_c',
Expand Down
19 changes: 11 additions & 8 deletions video/out/vulkan/context_wayland.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

struct priv {
struct mpvk_ctx vk;
bool use_fifo;
};

static bool wayland_vk_check_visible(struct ra_ctx *ctx)
Expand All @@ -35,8 +36,9 @@ static bool wayland_vk_check_visible(struct ra_ctx *ctx)
static void wayland_vk_swap_buffers(struct ra_ctx *ctx)
{
struct vo_wayland_state *wl = ctx->vo->wl;
struct priv *p = ctx->priv;

if (wl->opts->wl_internal_vsync)
if ((!p->use_fifo && wl->opts->wl_internal_vsync == 1) || wl->opts->wl_internal_vsync == 2)
vo_wayland_wait_frame(wl);

if (wl->use_present)
Expand All @@ -63,6 +65,7 @@ static bool wayland_vk_init(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv = talloc_zero(ctx, struct priv);
struct mpvk_ctx *vk = &p->vk;
struct vo_wayland_state *wl = ctx->vo->wl;
int msgl = ctx->opts.probing ? MSGL_V : MSGL_ERR;

if (!mpvk_init(vk, ctx, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME))
Expand Down Expand Up @@ -90,13 +93,13 @@ static bool wayland_vk_init(struct ra_ctx *ctx)
goto error;
}

/* Because in Wayland clients render whenever they receive a callback from
* the compositor, and the fact that the compositor usually stops sending
* callbacks once the surface is no longer visible, using FIFO here would
* mean the entire player would block on acquiring swapchain images. Hence,
* use MAILBOX to guarantee that there'll always be a swapchain image and
* the player won't block waiting on those */
if (!ra_vk_ctx_init(ctx, vk, params, VK_PRESENT_MODE_MAILBOX_KHR))
/* If the Wayland compositor does not support commit-timing and fifo
* protocols in addition to wp-presentation v2, the compositor will stop
* sending callbacks if the surface is no longer visible. This means using
* FIFO would block the entire vo thread which is just not good. Use MAILBOX
* for those compositors to avoid indefinite blocking. */
p->use_fifo = wl->has_commit_timing && wl->has_fifo && wl->present_v2;
if (!ra_vk_ctx_init(ctx, vk, params, p->use_fifo ? VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_MAILBOX_KHR))
goto error;

ra_add_native_resource(ctx->ra, "wl", ctx->vo->wl->display);
Expand Down
18 changes: 18 additions & 0 deletions video/out/wayland_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@
#include "cursor-shape-v1.h"
#endif

#if HAVE_WAYLAND_PROTOCOLS_1_38
#include "commit-timing-v1.h"
#include "fifo-v1.h"
#endif

#if WAYLAND_VERSION_MAJOR > 1 || WAYLAND_VERSION_MINOR >= 22
#define HAVE_WAYLAND_1_22
#endif
Expand Down Expand Up @@ -1578,6 +1583,18 @@ static void registry_handle_add(void *data, struct wl_registry *reg, uint32_t id
wl->single_pixel_manager = wl_registry_bind(reg, id, &wp_single_pixel_buffer_manager_v1_interface, ver);
}

#if HAVE_WAYLAND_PROTOCOLS_1_38
if (!strcmp(interface, wp_commit_timing_manager_v1_interface.name) && found++) {
ver = 1;
wl->has_commit_timing = true;
}

if (!strcmp(interface, wp_fifo_manager_v1_interface.name) && found++) {
ver = 1;
wl->has_fifo = true;
}
#endif

if (!strcmp(interface, wp_fractional_scale_manager_v1_interface.name) && found++) {
ver = 1;
wl->fractional_scale_manager = wl_registry_bind(reg, id, &wp_fractional_scale_manager_v1_interface, ver);
Expand All @@ -1592,6 +1609,7 @@ static void registry_handle_add(void *data, struct wl_registry *reg, uint32_t id

if (!strcmp(interface, wp_presentation_interface.name) && found++) {
ver = MPMIN(ver, 2);
wl->present_v2 = ver == 2;
wl->presentation = wl_registry_bind(reg, id, &wp_presentation_interface, ver);
wp_presentation_add_listener(wl->presentation, &pres_listener, wl);
}
Expand Down
7 changes: 7 additions & 0 deletions video/out/wayland_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ struct vo_wayland_state {
int timeout_count;
int wakeup_pipe[2];

/* commit-timing */
bool has_commit_timing;

/* content-type */
struct wp_content_type_manager_v1 *content_type_manager;
struct wp_content_type_v1 *content_type;
Expand All @@ -94,6 +97,9 @@ struct vo_wayland_state {
/* TODO: unvoid these if required wayland protocols is bumped to 1.32+ */
void *cursor_shape_manager;

/* fifo */
bool has_fifo;

/* fractional-scale */
struct wp_fractional_scale_manager_v1 *fractional_scale_manager;
struct wp_fractional_scale_v1 *fractional_scale;
Expand All @@ -116,6 +122,7 @@ struct vo_wayland_state {
struct mp_present *present;
int64_t refresh_interval;
bool present_clock;
bool present_v2;
bool use_present;

/* single-pixel-buffer */
Expand Down

0 comments on commit e84aa5e

Please sign in to comment.