summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/interface-changes.rst1
-rw-r--r--DOCS/man/options.rst6
-rw-r--r--generated/wayland/meson.build5
-rw-r--r--options/options.c5
-rw-r--r--options/options.h1
-rw-r--r--video/out/wayland_common.c50
-rw-r--r--video/out/wayland_common.h7
-rw-r--r--wscript5
-rw-r--r--wscript_build.py9
9 files changed, 89 insertions, 0 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst
index 83a8a17873..13757e8bc1 100644
--- a/DOCS/interface-changes.rst
+++ b/DOCS/interface-changes.rst
@@ -28,6 +28,7 @@ Interface changes
--- mpv 0.36.0 ---
- add `--force-render`
+ - add `--wayland-content-type`
--- mpv 0.35.0 ---
- add the `--vo=gpu-next` video output driver, as well as the options
`--allow-delayed-peak-detect`, `--builtin-scalers`,
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 3680cd0297..ed4505fb00 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -5587,6 +5587,12 @@ them.
it first renders. This option will take precedence over any ``autofit`` or
``geometry`` type settings if the configure bounds are used.
+``--wayland-content-type=<auto|none|photo|video|game>``
+ If supported by the compositor, mpv will send a hint using the content-type
+ protocol telling the compositor what type of content is being displayed. ``auto``
+ (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
diff --git a/generated/wayland/meson.build b/generated/wayland/meson.build
index 7811f849e9..919a280107 100644
--- a/generated/wayland/meson.build
+++ b/generated/wayland/meson.build
@@ -10,6 +10,11 @@ wl_protocols_headers = []
features += {'wayland_protocols_1_24': wayland['deps'][2].version().version_compare('>=1.24')}
+features += {'wayland_protocols_1_27': wayland['deps'][2].version().version_compare('>=1.27')}
+if features['wayland_protocols_1_27']
+ protocols += [[wl_protocol_dir, 'staging/content-type/content-type-v1.xml']]
+endif
+
foreach p: protocols
xml = join_paths(p)
wl_protocols_source += custom_target(xml.underscorify() + '_c',
diff --git a/options/options.c b/options/options.c
index ad8bde5fc8..8785d78182 100644
--- a/options/options.c
+++ b/options/options.c
@@ -179,6 +179,10 @@ static const m_option_t mp_vo_opt_list[] = {
{"x11-present", OPT_CHOICE(x11_present,
{"no", 0}, {"auto", 1}, {"yes", 2})},
#endif
+#if HAVE_WAYLAND
+ {"wayland-content-type", OPT_CHOICE(content_type, {"auto", -1}, {"none", 0},
+ {"photo", 1}, {"video", 2}, {"game", 3})},
+#endif
#if HAVE_WIN32_DESKTOP
{"vo-mmcss-profile", OPT_STRING(mmcss_profile)},
#endif
@@ -212,6 +216,7 @@ const struct m_sub_options vo_sub_opts = {
.border = 1,
.fit_border = 1,
.appid = "mpv",
+ .content_type = -1,
.WinID = -1,
.window_scale = 1.0,
.x11_bypass_compositor = 2,
diff --git a/options/options.h b/options/options.h
index 2956ade751..5560f40554 100644
--- a/options/options.h
+++ b/options/options.h
@@ -27,6 +27,7 @@ typedef struct mp_vo_opts {
char *fsscreen_name;
char *winname;
char *appid;
+ int content_type;
int x11_netwm;
int x11_bypass_compositor;
int x11_present;
diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c
index 53854c2465..6efd099ceb 100644
--- a/video/out/wayland_common.c
+++ b/video/out/wayland_common.c
@@ -42,6 +42,10 @@
#include "generated/wayland/xdg-shell.h"
#include "generated/wayland/viewporter.h"
+#if HAVE_WAYLAND_PROTOCOLS_1_27
+#include "generated/wayland/content-type-v1.h"
+#endif
+
#if WAYLAND_VERSION_MAJOR > 1 || WAYLAND_VERSION_MINOR >= 20
#define HAVE_WAYLAND_1_20
#endif
@@ -1232,6 +1236,12 @@ static void registry_handle_add(void *data, struct wl_registry *reg, uint32_t id
wl->shm = wl_registry_bind(reg, id, &wl_shm_interface, 1);
}
+#if HAVE_WAYLAND_PROTOCOLS_1_27
+ if (!strcmp(interface, wp_content_type_manager_v1_interface.name) && found++) {
+ wl->content_type_manager = wl_registry_bind(reg, id, &wp_content_type_manager_v1_interface, 1);
+ }
+#endif
+
if (!strcmp(interface, wp_presentation_interface.name) && found++) {
wl->presentation = wl_registry_bind(reg, id, &wp_presentation_interface, 1);
wp_presentation_add_listener(wl->presentation, &pres_listener, wl);
@@ -1520,6 +1530,20 @@ static void remove_output(struct vo_wayland_output *out)
return;
}
+static void set_content_type(struct vo_wayland_state *wl)
+{
+ if (!wl->content_type_manager)
+ return;
+#if HAVE_WAYLAND_PROTOCOLS_1_27
+ // handle auto;
+ if (wl->vo_opts->content_type == -1) {
+ wp_content_type_v1_set_content_type(wl->content_type, wl->current_content_type);
+ } else {
+ wp_content_type_v1_set_content_type(wl->content_type, wl->vo_opts->content_type);
+ }
+#endif
+}
+
static int set_cursor_visibility(struct vo_wayland_state *wl, bool on)
{
wl->cursor_visible = on;
@@ -1803,6 +1827,8 @@ int vo_wayland_control(struct vo *vo, int *events, int request, void *arg)
&wl->vo_opts->border);
}
}
+ if (opt == &opts->content_type)
+ set_content_type(wl);
if (opt == &opts->fullscreen)
toggle_fullscreen(wl);
if (opt == &opts->hidpi_window_scale)
@@ -1825,6 +1851,13 @@ int vo_wayland_control(struct vo *vo, int *events, int request, void *arg)
}
return VO_TRUE;
}
+ case VOCTRL_CONTENT_TYPE: {
+#if HAVE_WAYLAND_PROTOCOLS_1_27
+ wl->current_content_type = (enum mp_content_type)arg;
+ set_content_type(wl);
+#endif
+ return VO_TRUE;
+ }
case VOCTRL_GET_FOCUSED: {
*(bool *)arg = wl->focused;
return VO_TRUE;
@@ -1967,6 +2000,15 @@ int vo_wayland_init(struct vo *vo)
if (xdg_current_desktop != NULL && strstr(xdg_current_desktop, "GNOME"))
MP_WARN(wl, "GNOME's wayland compositor lacks support for the idle inhibit protocol. This means the screen can blank during playback.\n");
+#if HAVE_WAYLAND_PROTOCOLS_1_27
+ if (wl->content_type_manager) {
+ wl->content_type = wp_content_type_manager_v1_get_surface_content_type(wl->content_type_manager, wl->surface);
+ } else {
+ MP_VERBOSE(wl, "Compositor doesn't support the %s protocol!\n",
+ wp_content_type_manager_v1_interface.name);
+ }
+#endif
+
if (wl->dnd_devman && wl->seat) {
wl->dnd_ddev = wl_data_device_manager_get_data_device(wl->dnd_devman, wl->seat);
wl_data_device_add_listener(wl->dnd_ddev, &data_device_listener, wl);
@@ -2119,6 +2161,14 @@ void vo_wayland_uninit(struct vo *vo)
if (wl->cursor_theme)
wl_cursor_theme_destroy(wl->cursor_theme);
+#if HAVE_WAYLAND_PROTOCOLS_1_27
+ if (wl->content_type)
+ wp_content_type_v1_destroy(wl->content_type);
+
+ if (wl->content_type_manager)
+ wp_content_type_manager_v1_destroy(wl->content_type_manager);
+#endif
+
if (wl->dnd_ddev)
wl_data_device_destroy(wl->dnd_ddev);
diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h
index 541b4d0d28..627ea0d057 100644
--- a/video/out/wayland_common.h
+++ b/video/out/wayland_common.h
@@ -24,6 +24,7 @@
struct wayland_opts {
int configure_bounds;
+ int content_type;
int disable_vsync;
int edge_pixels_pointer;
int edge_pixels_touch;
@@ -77,6 +78,12 @@ struct vo_wayland_state {
int timeout_count;
int wakeup_pipe[2];
+ /* content-type */
+ /* TODO: unvoid these if required wayland protocols is bumped to 1.27+ */
+ void *content_type_manager;
+ void *content_type;
+ int current_content_type;
+
/* idle-inhibit */
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager;
struct zwp_idle_inhibitor_v1 *idle_inhibitor;
diff --git a/wscript b/wscript
index e349d4103e..9fc7583225 100644
--- a/wscript
+++ b/wscript
@@ -536,6 +536,11 @@ video_output_features = [
'deps': 'wayland',
'func': check_pkg_config('wayland-protocols >= 1.24'),
} , {
+ 'name': 'wayland-protocols-1-27',
+ 'desc': 'wayland-protocols version 1.27+',
+ 'deps': 'wayland',
+ 'func': check_pkg_config('wayland-protocols >= 1.27'),
+ } , {
'name': 'memfd_create',
'desc': "Linux's memfd_create()",
'deps': 'wayland',
diff --git a/wscript_build.py b/wscript_build.py
index 16c8cf0895..1621b94b97 100644
--- a/wscript_build.py
+++ b/wscript_build.py
@@ -140,6 +140,14 @@ def build(ctx):
protocol = "stable/viewporter/viewporter",
target = "generated/wayland/viewporter.h")
+ if ctx.dependency_satisfied('wayland-protocols-1-27'):
+ ctx.wayland_protocol_code(proto_dir = ctx.env.WL_PROTO_DIR,
+ protocol = "staging/content-type/content-type-v1",
+ target = "generated/wayland/content-type-v1.c")
+ ctx.wayland_protocol_header(proto_dir = ctx.env.WL_PROTO_DIR,
+ protocol = "staging/content-type/content-type-v1",
+ target = "generated/wayland/content-type-v1.h")
+
ctx(features = "ebml_header", target = "generated/ebml_types.h")
ctx(features = "ebml_definitions", target = "generated/ebml_defs.inc")
@@ -540,6 +548,7 @@ def build(ctx):
( "video/out/vulkan/context_xlib.c", "vulkan && x11" ),
( "video/out/vulkan/utils.c", "vulkan" ),
( "video/out/w32_common.c", "win32-desktop" ),
+ ( "generated/wayland/content-type-v1.c", "wayland-protocols-1-27" ),
( "generated/wayland/idle-inhibit-unstable-v1.c", "wayland" ),
( "generated/wayland/presentation-time.c", "wayland" ),
( "generated/wayland/xdg-decoration-unstable-v1.c", "wayland" ),