diff options
-rw-r--r-- | video/out/vo_dmabuf_wayland.c | 6 | ||||
-rw-r--r-- | video/out/wayland_common.c | 87 | ||||
-rw-r--r-- | video/out/wayland_common.h | 6 |
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); |