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 21, 2024
1 parent aba5b14 commit 35a00d7
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 10 deletions.
5 changes: 4 additions & 1 deletion DOCS/man/options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6024,7 +6024,10 @@ them.
Controls whether to use mpv's internal vsync for Wayland-base video outputs
(default: ``auto``). This is mainly useful for benchmarking wayland VOs when
combined with ``video-sync=display-desync``, ``--audio=no``, and
``--untimed=yes``.
``--untimed=yes``. The special ``auto`` value will disable the internal
vsync if the compositor supports the commit-timing and fifo protocols when
using ``--gpu-api=vulkan``. In any other situation, it is exactly the same
as ``yes``.

``--wayland-present=<yes|no>``
Enable the use of wayland's presentation time protocol for more accurate
Expand Down
7 changes: 6 additions & 1 deletion video/out/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,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 @@ -22,6 +22,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 Down Expand Up @@ -90,13 +92,14 @@ 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, fifo, and
* presentation time v2 protocols, 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. */
struct vo_wayland_state *wl = ctx->vo->wl;
p->use_fifo = wl->has_commit_timing && wl->has_fifo && wl->present_v2 && wl->use_present;
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 @@ -59,6 +59,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 @@ -1720,6 +1725,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 @@ -1734,6 +1751,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 @@ -103,6 +103,9 @@ struct vo_wayland_state {
int primaries_map[PL_COLOR_PRIM_COUNT];
int transfer_map[PL_COLOR_TRC_COUNT];

/* 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 @@ -112,6 +115,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 @@ -134,6 +140,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 35a00d7

Please sign in to comment.