Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wayland_vk: use FIFO if commit-timing and fifo protocols are available #15056

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions DOCS/interface-changes/wayland-internal-vsync.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
deprecate `--wayland-disable-vsync`
add `--wayland-internal-vsync` as a replacement for `--wayland-disable-vsync`
14 changes: 9 additions & 5 deletions DOCS/man/options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6096,11 +6096,6 @@ them.
(default) will automatically switch between telling the compositor the content
is a photo, video or possibly none depending on internal heuristics.

``--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``.

``--wayland-edge-pixels-pointer=<value>``
Defines the size of an edge border (default: 16) to initiate client side
resize events in the wayland contexts with the mouse. This is only active if
Expand All @@ -6110,6 +6105,15 @@ them.
Defines the size of an edge border (default: 32) to initiate client side
resizes events in the wayland contexts with touch events.

``--wayland-internal-vsync=<no|auto|yes>``
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``. 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
frame presentation if it is supported by the compositor (default: ``yes``).
Expand Down
5 changes: 4 additions & 1 deletion options/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,10 @@ static const m_option_t mp_vo_opt_list[] = {
{"auto", -1}, {"no", 0}, {"yes", 1})},
{"wayland-content-type", OPT_CHOICE(wl_content_type, {"auto", -1}, {"none", 0},
{"photo", 1}, {"video", 2}, {"game", 3})},
{"wayland-disable-vsync", OPT_BOOL(wl_disable_vsync)},
{"wayland-disable-vsync", OPT_BOOL(wl_disable_vsync),
.deprecation_message = "replaced by --wayland-internal-vsync=no"},
{"wayland-internal-vsync", OPT_CHOICE(wl_internal_vsync,
{"no", 0}, {"auto", 1}, {"yes", 2})},
{"wayland-edge-pixels-pointer", OPT_INT(wl_edge_pixels_pointer),
M_RANGE(0, INT_MAX)},
{"wayland-edge-pixels-touch", OPT_INT(wl_edge_pixels_touch),
Expand Down
1 change: 1 addition & 0 deletions options/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ typedef struct mp_vo_opts {
int wl_configure_bounds;
int wl_content_type;
bool wl_disable_vsync;
int wl_internal_vsync;
int wl_edge_pixels_pointer;
int wl_edge_pixels_touch;
bool wl_present;
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
2 changes: 1 addition & 1 deletion video/out/opengl/context_wayland.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ static void wayland_egl_swap_buffers(struct ra_ctx *ctx)

eglSwapBuffers(p->egl_display, p->egl_surface);

if (!wl->opts->wl_disable_vsync)
if (wl->opts->wl_internal_vsync)
vo_wayland_wait_frame(wl);

if (wl->use_present)
Expand Down
2 changes: 1 addition & 1 deletion video/out/vo_dmabuf_wayland.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ static void flip_page(struct vo *vo)
wl_surface_commit(wl->osd_surface);
wl_surface_commit(wl->surface);

if (!wl->opts->wl_disable_vsync)
if (wl->opts->wl_internal_vsync)
vo_wayland_wait_frame(wl);

if (wl->use_present)
Expand Down
2 changes: 1 addition & 1 deletion video/out/vo_wlshm.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ static void flip_page(struct vo *vo)
vo->dheight);
wl_surface_commit(wl->surface);

if (!wl->opts->wl_disable_vsync)
if (wl->opts->wl_internal_vsync)
vo_wayland_wait_frame(wl);

if (wl->use_present)
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_disable_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->opts->wl_internal_vsync != 2;
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 @@ -1760,6 +1765,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 @@ -1774,6 +1791,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 @@ -104,6 +104,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 @@ -113,6 +116,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 @@ -135,6 +141,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
Loading