From 027ca4fb855f3dff4cba1c907c92c509b82e6fe8 Mon Sep 17 00:00:00 2001 From: dudemanguy Date: Mon, 14 Oct 2019 12:16:42 -0500 Subject: [PATCH] wayland: add various render-related options The newest wayland changes have some new logic that make sense to expose to users as configurable options. --- DOCS/man/options.rst | 15 +++++++++++++++ options/options.c | 5 +++++ options/options.h | 1 + video/out/opengl/context_wayland.c | 3 ++- video/out/vulkan/context_wayland.c | 3 ++- video/out/wayland_common.c | 20 ++++++++++++++++++-- video/out/wayland_common.h | 8 +++++++- 7 files changed, 50 insertions(+), 5 deletions(-) diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 008867feab..f9516d1787 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -4751,6 +4751,21 @@ The following video options are currently all specific to ``--vo=gpu`` and Currently only relevant for ``--gpu-api=d3d11``. +``--wayland-frame-wait-offset=<-100..3000>`` + Control the amount of offset (in microseconds) to add to wayland's frame wait + (default 1000). The wayland context assumes that if frame callback or presentation + feedback isn't received within a certain amount of time then the video is being + rendered offscreen. The time it waits is equal to how long it takes your monitor + to display a frame (i.e. 1/refresh rate) plus the offset. In general, staying + close to your monitor's refresh rate is preferred, but with a small offset in + case a frame takes a little long to display. + +``--wayland-disable-vsync=`` + Disable vsync for the wayland contexts (default: no). Useful for benchmarking + the wayland context when combined with ``video-sync=display-desync``, + ``--no-audio``, and ``--untimed=yes``. Only works with ``--gpu-context=wayland`` + and ``--gpu-context=waylandvk``. + ``--spirv-compiler=`` Controls which compiler is used to translate GLSL to SPIR-V. This is (currently) only relevant for ``--gpu-api=vulkan`` and `--gpu-api=d3d11`. diff --git a/options/options.c b/options/options.c index d8654c2146..6743e320da 100644 --- a/options/options.c +++ b/options/options.c @@ -92,6 +92,7 @@ extern const struct m_sub_options angle_conf; extern const struct m_sub_options cocoa_conf; extern const struct m_sub_options macos_conf; extern const struct m_sub_options android_conf; +extern const struct m_sub_options wayland_conf; extern const struct m_sub_options vaapi_conf; static const struct m_sub_options screenshot_conf = { @@ -750,6 +751,10 @@ const m_option_t mp_opts[] = { OPT_SUBSTRUCT("", android_opts, android_conf, 0), #endif +#if HAVE_WAYLAND + OPT_SUBSTRUCT("", wayland_opts, wayland_conf, 0), +#endif + #if HAVE_GL_WIN32 OPT_CHOICE("opengl-dwmflush", wingl_dwm_flush, 0, ({"no", -1}, {"auto", 0}, {"windowed", 1}, {"yes", 2})), diff --git a/options/options.h b/options/options.h index fb5f842565..c0f01ae5dc 100644 --- a/options/options.h +++ b/options/options.h @@ -336,6 +336,7 @@ typedef struct MPOpts { struct cocoa_opts *cocoa_opts; struct macos_opts *macos_opts; struct android_opts *android_opts; + struct wayland_opts *wayland_opts; struct dvd_opts *dvd_opts; struct vaapi_opts *vaapi_opts; diff --git a/video/out/opengl/context_wayland.c b/video/out/opengl/context_wayland.c index 5e9150eb0d..917db8553c 100644 --- a/video/out/opengl/context_wayland.c +++ b/video/out/opengl/context_wayland.c @@ -139,7 +139,8 @@ static void wayland_egl_swap_buffers(struct ra_ctx *ctx) } eglSwapBuffers(p->egl_display, p->egl_surface); - vo_wayland_wait_frame(wl); + if (!wl->opts->disable_vsync) + vo_wayland_wait_frame(wl, wl->opts->frame_offset); if (wl->presentation) wayland_sync_swap(wl); diff --git a/video/out/vulkan/context_wayland.c b/video/out/vulkan/context_wayland.c index d3da628137..6abec91aaf 100644 --- a/video/out/vulkan/context_wayland.c +++ b/video/out/vulkan/context_wayland.c @@ -110,7 +110,8 @@ static void wayland_vk_swap_buffers(struct ra_ctx *ctx) queue_new_sync(wl); } - vo_wayland_wait_frame(wl); + if (!wl->opts->disable_vsync) + vo_wayland_wait_frame(wl, wl->opts->frame_offset); if (wl->presentation) wayland_sync_swap(wl); diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index f66753018b..0b749a526d 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -22,6 +22,7 @@ #include #include #include "common/msg.h" +#include "options/m_config.h" #include "input/input.h" #include "input/keycodes.h" #include "osdep/io.h" @@ -41,6 +42,20 @@ // Generated from presentation-time.xml #include "video/out/wayland/presentation-time.h" +#define OPT_BASE_STRUCT struct wayland_opts +const struct m_sub_options wayland_conf = { + .opts = (const struct m_option[]) { + OPT_INTRANGE("wayland-frame-wait-offset", frame_offset, 0, -500, 3000), + OPT_FLAG("wayland-disable-vsync", disable_vsync, 0), + {0}, + }, + .size = sizeof(struct wayland_opts), + .defaults = &(struct wayland_opts) { + .frame_offset = 1000, + .disable_vsync = false, + }, +}; + static void xdg_wm_base_ping(void *data, struct xdg_wm_base *wm_base, uint32_t serial) { xdg_wm_base_pong(wm_base, serial); @@ -1100,6 +1115,7 @@ int vo_wayland_init(struct vo *vo) MP_VERBOSE(wl, "Compositor doesn't support the %s protocol!\n", zwp_idle_inhibit_manager_v1_interface.name); + wl->opts = mp_get_config_group(wl, wl->vo->global, &wayland_conf); wl->display_fd = wl_display_get_fd(wl->display); mp_make_wakeup_pipe(wl->wakeup_pipe); @@ -1511,14 +1527,14 @@ void vo_wayland_wakeup(struct vo *vo) (void)write(wl->wakeup_pipe[1], &(char){0}, 1); } -void vo_wayland_wait_frame(struct vo_wayland_state *wl) +void vo_wayland_wait_frame(struct vo_wayland_state *wl, int frame_offset) { struct pollfd fds[1] = { {.fd = wl->display_fd, .events = POLLIN }, }; double vblank_time = 1e6 / wl->current_output->refresh_rate; - int64_t finish_time = mp_time_us() + vblank_time + 1000; + int64_t finish_time = mp_time_us() + vblank_time + (int64_t)frame_offset; while (wl->frame_wait && finish_time > mp_time_us()) { diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h index 606d9ed218..0e9705cce8 100644 --- a/video/out/wayland_common.h +++ b/video/out/wayland_common.h @@ -25,6 +25,11 @@ #include "vo.h" #include "input/event.h" +struct wayland_opts { + int frame_offset; + int disable_vsync; +}; + struct vo_wayland_sync { int64_t ust; int64_t msc; @@ -56,6 +61,7 @@ struct vo_wayland_state { struct wl_shm *shm; struct wl_compositor *compositor; struct wl_registry *registry; + struct wayland_opts *opts; /* State */ struct mp_rect geometry; @@ -136,7 +142,7 @@ void vo_wayland_check_events(struct vo *vo); void vo_wayland_uninit(struct vo *vo); void vo_wayland_wakeup(struct vo *vo); void vo_wayland_wait_events(struct vo *vo, int64_t until_time_us); -void vo_wayland_wait_frame(struct vo_wayland_state *wl); +void vo_wayland_wait_frame(struct vo_wayland_state *wl, int frame_offset); void wayland_sync_swap(struct vo_wayland_state *wl); void vo_wayland_sync_shift(struct vo_wayland_state *wl); void queue_new_sync(struct vo_wayland_state *wl);