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 ba3b4ed commit 3113c9a
Show file tree
Hide file tree
Showing 5 changed files with 42 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 @@ -6014,7 +6014,10 @@ them.
``--wayland-disable-vsync=<yes|no>``
Disable mpv's internal vsync for Wayland-based video output (default: no).
This is mainly useful for benchmarking wayland VOs when combined with
``video-sync=display-desync``, ``--audio=no``, and ``--untimed=yes``.
``video-sync=display-desync``, ``--audio=no``, and ``--untimed=yes``. This
option has no affect if using ``--gpu-api=vulkan`` on a compositor that
supports the commit-timing and fifo protocols since mpv's internal vsync is
not used at all in that case.

``--wayland-edge-pixels-pointer=<value>``
Defines the size of an edge border (default: 16) to initiate client side
Expand Down
8 changes: 7 additions & 1 deletion video/out/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ protocols = [[wl_protocol_dir, 'stable/presentation-time/presentation-time.xml']
wl_protocols_source = []
wl_protocols_headers = []

foreach v: ['1.32']
# TODO: bump this to 1.38 when it comes out
foreach v: ['1.32', '1.37']
features += {'wayland-protocols-' + v.replace('.', '-'):
wayland['deps'][2].version().version_compare('>=' + v)}
endforeach
Expand All @@ -21,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-37']
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
18 changes: 10 additions & 8 deletions video/out/vulkan/context_wayland.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ static void wayland_vk_swap_buffers(struct ra_ctx *ctx)
{
struct vo_wayland_state *wl = ctx->vo->wl;

if (!wl->opts->wl_disable_vsync)
if (!wl->has_commit_timing || !wl->has_fifo || !wl->opts->wl_disable_vsync)
vo_wayland_wait_frame(wl);

if (wl->use_present)
Expand All @@ -63,6 +63,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 +91,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 and fifo
* protocols, the compositor will stop sending callbacks if the surface is
* no longer visible. That means using FIFO would block the entire vo thread
* which is just not good. Use MAILBOX for those compositors to avoid
* indefinite blocking. */
VkPresentModeKHR mode = wl->has_commit_timing && wl->has_fifo ? VK_PRESENT_MODE_FIFO_KHR :
VK_PRESENT_MODE_MAILBOX_KHR;
if (!ra_vk_ctx_init(ctx, vk, params, mode))
goto error;

ra_add_native_resource(ctx->ra, "wl", ctx->vo->wl->display);
Expand Down
15 changes: 15 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_37
#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 @@ -1568,6 +1573,11 @@ static void registry_handle_add(void *data, struct wl_registry *reg, uint32_t id
wl->shm = wl_registry_bind(reg, id, &wl_shm_interface, ver);
}

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

if (!strcmp(interface, wp_content_type_manager_v1_interface.name) && found++) {
ver = 1;
wl->content_type_manager = wl_registry_bind(reg, id, &wp_content_type_manager_v1_interface, ver);
Expand All @@ -1578,6 +1588,11 @@ 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 (!strcmp(interface, wp_fifo_manager_v1_interface.name) && found++) {
ver = 1;
wl->has_fifo = true;
}

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 Down
6 changes: 6 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 Down

0 comments on commit 3113c9a

Please sign in to comment.