summaryrefslogtreecommitdiffstats
path: root/video/out/wayland_common.c
diff options
context:
space:
mode:
authorDudemanguy <random342@airmail.cc>2022-11-15 15:51:45 -0600
committerDudemanguy <random342@airmail.cc>2022-11-15 23:18:55 +0000
commit6623efb14223f8d4ebb0b2b966b21f5953eb56a9 (patch)
treedcb6d74e90e794bcf1ccb3bea5527ca4c0089ccd /video/out/wayland_common.c
parentbab85944df3ae114a4d411fe7b0f243d4d222222 (diff)
downloadmpv-6623efb14223f8d4ebb0b2b966b21f5953eb56a9.tar.bz2
mpv-6623efb14223f8d4ebb0b2b966b21f5953eb56a9.tar.xz
wayland: add support for content-type protocol
The content-type protocol allows mpv to send compositor a hint about the type of content being displayed on its surface so it could potentially make some sort of optimization. Fundamentally, this is pretty simple but since this requires a very new wayland-protocols version (1.27), we have to mess with the build to add a new define and add a bunch of if's in here. The protocol itself exposes 4 different types of content: none, photo, video, and game. To do that, let's add a new option (wayland-content-type) that lets users control what hint to send to the compossitor. Since the previous commit adds a VOCTRL that notifies us about the content being displayed, we can also add an auto value to this option. As you'd expect, the compositor hint would be set to photo if mpv's core detects an image, video for other things, and it is set to none for the special case of forcing a window when there is not a video track. For completion's sake, game is also allowed as a value for this option, but in practice there shouldn't be a reason to use that.
Diffstat (limited to 'video/out/wayland_common.c')
-rw-r--r--video/out/wayland_common.c50
1 files changed, 50 insertions, 0 deletions
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);