summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/out/vo_dmabuf_wayland.c6
-rw-r--r--video/out/wayland_common.c87
-rw-r--r--video/out/wayland_common.h6
3 files changed, 88 insertions, 11 deletions
diff --git a/video/out/vo_dmabuf_wayland.c b/video/out/vo_dmabuf_wayland.c
index f3c1fe36f9..17ead0066d 100644
--- a/video/out/vo_dmabuf_wayland.c
+++ b/video/out/vo_dmabuf_wayland.c
@@ -75,11 +75,11 @@ static bool vaapi_dmabuf_importer(struct mp_image *src, struct wlbuf_pool_entry*
int layer_no = 0;
VAStatus status = vaExportSurfaceHandle(p->display, entry->key, VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
VA_EXPORT_SURFACE_COMPOSED_LAYERS | VA_EXPORT_SURFACE_READ_ONLY, &desc);
-
if (status == VA_STATUS_ERROR_INVALID_SURFACE) {
MP_VERBOSE(entry->vo, "VA export to composed layers not supported.\n");
- } else if (!vo_wayland_supported_format(entry->vo, desc.layers[layer_no].drm_format)) {
- MP_VERBOSE(entry->vo, "%s is not supported.\n", mp_tag_str(desc.layers[layer_no].drm_format));
+ } else if (!vo_wayland_supported_format(entry->vo, desc.layers[0].drm_format, desc.objects[0].drm_format_modifier)) {
+ MP_VERBOSE(entry->vo, "%s(%016lx) is not supported.\n",
+ mp_tag_str(desc.layers[0].drm_format), desc.objects[0].drm_format_modifier);
} else if (CHECK_VA_STATUS(entry->vo, "vaExportSurfaceHandle()")) {
entry->drm_format = desc.layers[layer_no].drm_format;
for (int plane_no = 0; plane_no < desc.layers[layer_no].num_planes; ++plane_no) {
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);
diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h
index 77699a3dd6..fdb745c5d3 100644
--- a/video/out/wayland_common.h
+++ b/video/out/wayland_common.h
@@ -83,6 +83,10 @@ struct vo_wayland_state {
/* linux-dmabuf */
struct zwp_linux_dmabuf_v1 *dmabuf;
+ struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback;
+ void *format_map;
+ uint32_t format_size;
+ /* TODO: remove these once zwp_linux_dmabuf_v1 version 2 support is removed. */
int *drm_formats;
int drm_format_ct;
int drm_format_ct_max;
@@ -138,7 +142,7 @@ struct vo_wayland_state {
};
bool vo_wayland_check_visible(struct vo *vo);
-bool vo_wayland_supported_format(struct vo *vo, uint32_t format);
+bool vo_wayland_supported_format(struct vo *vo, uint32_t format, uint64_t modifier);
int vo_wayland_allocate_memfd(struct vo *vo, size_t size);
int vo_wayland_control(struct vo *vo, int *events, int request, void *arg);