summaryrefslogtreecommitdiffstats
path: root/video/out/wayland_common.c
diff options
context:
space:
mode:
authorEmmanuel Gil Peyrot <linkmauve@linkmauve.fr>2022-07-07 12:03:21 +0200
committerDudemanguy <random342@airmail.cc>2022-10-26 18:41:47 +0000
commit666cb91cf12a4f8b42087530104513b0fc4ba16d (patch)
treed4a0f88472c64a4c20fe77d2b0cff232e03df0db /video/out/wayland_common.c
parentaeb4792cb6804a78974faa329a9c9f8a7bb5fa7b (diff)
downloadmpv-666cb91cf12a4f8b42087530104513b0fc4ba16d.tar.bz2
mpv-666cb91cf12a4f8b42087530104513b0fc4ba16d.tar.xz
wayland: bump dmabuf protocol to version 4
Pulled from https://github.com/mpv-player/mpv/pull/10382 The zwp_linux_dmabuf_v1 protocol version 4 provides a file descriptor containing both formats and modifiers, which makes it possible for the compositor to import the buffers onto planes using explicit modifiers. This is an extremely important efficiency improvement, as the 3D hardware can be left powered off altogether, the vaapi buffer being sent directly from the video hardware to the display controller. It could be possible to support zwp_linux_dmabuf_v1 version 3 as well, but there is no reason beyond compatibility with old stacks. I would recommend to ditch version 2 as well, as modifier-less formats aren’t very useful nowadays.
Diffstat (limited to 'video/out/wayland_common.c')
-rw-r--r--video/out/wayland_common.c87
1 files changed, 80 insertions, 7 deletions
diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c
index ba2fba7f78..9c8dd1a6a1 100644
--- a/video/out/wayland_common.c
+++ b/video/out/wayland_common.c
@@ -1071,14 +1071,68 @@ static void dmabuf_format(void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmab
MP_VERBOSE(wl, "%s is supported by the compositor.\n", mp_tag_str(format));
}
-static void dmabuf_modifier(void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf,
- uint32_t format, uint32_t modifier_hi, uint32_t modifier_lo)
+static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = {
+ dmabuf_format
+};
+
+static void done(void *data,
+ struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1)
{
}
-static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = {
- dmabuf_format,
- dmabuf_modifier
+static void format_table(void *data,
+ struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
+ int32_t fd,
+ uint32_t size)
+{
+ struct vo_wayland_state *wl = data;
+
+ void *map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
+ close(fd);
+
+ if (map != MAP_FAILED) {
+ wl->format_map = map;
+ wl->format_size = size;
+ }
+}
+
+static void main_device(void *data,
+ struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
+ struct wl_array *device)
+{
+}
+
+static void tranche_done(void *data,
+ struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1)
+{
+}
+
+static void tranche_target_device(void *data,
+ struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
+ struct wl_array *device)
+{
+}
+
+static void tranche_formats(void *data,
+ struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
+ struct wl_array *indices)
+{
+}
+
+static void tranche_flags(void *data,
+ struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
+ uint32_t flags)
+{
+}
+
+static const struct zwp_linux_dmabuf_feedback_v1_listener dmabuf_feedback_listener = {
+ done,
+ format_table,
+ main_device,
+ tranche_done,
+ tranche_target_device,
+ tranche_formats,
+ tranche_flags,
};
static void registry_handle_add(void *data, struct wl_registry *reg, uint32_t id,
@@ -1103,7 +1157,12 @@ static void registry_handle_add(void *data, struct wl_registry *reg, uint32_t id
wl->subcompositor = wl_registry_bind(reg, id, &wl_subcompositor_interface, 1);
}
- if (!strcmp (interface, zwp_linux_dmabuf_v1_interface.name) && (ver >= 2) && found++) {
+ if (!strcmp (interface, zwp_linux_dmabuf_v1_interface.name) && (ver >= 4) && found++) {
+ wl->dmabuf = wl_registry_bind(reg, id, &zwp_linux_dmabuf_v1_interface, 4);
+ wl->dmabuf_feedback = zwp_linux_dmabuf_v1_get_default_feedback(wl->dmabuf);
+ zwp_linux_dmabuf_feedback_v1_add_listener(wl->dmabuf_feedback, &dmabuf_feedback_listener, wl);
+ }
+ else if (!strcmp (interface, zwp_linux_dmabuf_v1_interface.name) && (ver >= 2) && found++) {
wl->dmabuf = wl_registry_bind(reg, id, &zwp_linux_dmabuf_v1_interface, 2);
zwp_linux_dmabuf_v1_add_listener(wl->dmabuf, &dmabuf_listener, wl);
wl->drm_format_ct_max = 64;
@@ -1964,10 +2023,22 @@ void vo_wayland_set_opaque_region(struct vo_wayland_state *wl, int alpha)
}
}
-bool vo_wayland_supported_format(struct vo *vo, uint32_t drm_format)
+bool vo_wayland_supported_format(struct vo *vo, uint32_t drm_format, uint64_t modifier)
{
struct vo_wayland_state *wl = vo->wl;
+ const struct {
+ uint32_t format;
+ uint32_t padding;
+ uint64_t modifier;
+ } *formats = wl->format_map;
+
+ for (int i = 0; i < wl->format_size / 16; ++i) {
+ if (drm_format == formats[i].format && modifier == formats[i].modifier)
+ return true;
+ }
+
+ /* TODO: remove these once zwp_linux_dmabuf_v1 version 2 support is removed. */
for (int i = 0; i < wl->drm_format_ct; ++i) {
if (drm_format == wl->drm_formats[i])
return true;
@@ -2088,6 +2159,8 @@ void vo_wayland_uninit(struct vo *vo)
wl_display_disconnect(wl->display);
}
+ munmap(wl->format_map, wl->format_size);
+
struct vo_wayland_output *output, *tmp;
wl_list_for_each_safe(output, tmp, &wl->output_list, link)
remove_output(output);