From: yuq825@gmail.com
To: qemu-devel@nongnu.org
Cc: "Marc-André Lureau" <marcandre.lureau@redhat.com>,
"Qiang Yu" <yuq825@gmail.com>
Subject: [PATCH 5/6] ui/dbus: change dbus ScanoutDMABUF interface
Date: Mon, 24 Mar 2025 16:19:20 +0800 [thread overview]
Message-ID: <20250324081922.359369-6-yuq825@gmail.com> (raw)
In-Reply-To: <20250324081922.359369-1-yuq825@gmail.com>
From: Qiang Yu <yuq825@gmail.com>
To handle multi plane.
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
ui/dbus-display1.xml | 37 ++++++++++++++++
ui/dbus-listener.c | 103 ++++++++++++++++++++++++++++++++++++++++---
2 files changed, 133 insertions(+), 7 deletions(-)
diff --git a/ui/dbus-display1.xml b/ui/dbus-display1.xml
index 72deefa455..c1d1a402b7 100644
--- a/ui/dbus-display1.xml
+++ b/ui/dbus-display1.xml
@@ -614,6 +614,43 @@
</method>
</interface>
+ <!--
+ org.qemu.Display1.Listener.Unix.MultiPlane:
+
+ This optional client-side interface can complement
+ org.qemu.Display1.Listener on ``/org/qemu/Display1/Listener`` for
+ Unix-specific multi plane DMABUF scanout setup.
+ -->
+ <?if $(env.HOST_OS) != windows?>
+ <interface name="org.qemu.Display1.Listener.Unix.MultiPlane">
+ <!--
+ ScanoutDMABUF2:
+ @dmabuf: DMABUF file descriptor of each plane.
+ @width: display width, in pixels.
+ @height: display height, in pixels.
+ @offset: offset of each plane, in bytes.
+ @stride: stride of each plane, in bytes.
+ @num_planes: plane number.
+ @fourcc: DMABUF fourcc.
+ @modifier: DMABUF modifier.
+ @y0_top: whether Y position 0 is the top or not.
+
+ Resize and update the display content with DMABUF.
+ -->
+ <method name="ScanoutDMABUF2">
+ <arg type="ah" name="dmabuf" direction="in"/>
+ <arg type="u" name="width" direction="in"/>
+ <arg type="u" name="height" direction="in"/>
+ <arg type="au" name="offset" direction="in"/>
+ <arg type="au" name="stride" direction="in"/>
+ <arg type="u" name="num_planes" direction="in"/>
+ <arg type="u" name="fourcc" direction="in"/>
+ <arg type="t" name="modifier" direction="in"/>
+ <arg type="b" name="y0_top" direction="in"/>
+ </method>
+ </interface>
+ <?endif?>
+
<!--
org.qemu.Display1.Clipboard:
diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c
index 73b72ed57c..b7b455a595 100644
--- a/ui/dbus-listener.c
+++ b/ui/dbus-listener.c
@@ -85,6 +85,7 @@ struct _DBusDisplayListener {
#endif
#else /* !WIN32 */
QemuDBusDisplay1ListenerUnixMap *map_proxy;
+ QemuDBusDisplay1ListenerUnixMultiPlane *multi_plane_proxy;
#endif
guint dbus_filter;
@@ -288,10 +289,9 @@ static void dbus_call_update_gl(DisplayChangeListener *dcl,
}
#ifdef CONFIG_GBM
-static void dbus_scanout_dmabuf(DisplayChangeListener *dcl,
- QemuDmaBuf *dmabuf)
+static void dbus_scanout_dmabuf_single_plane(DBusDisplayListener *ddl,
+ QemuDmaBuf *dmabuf)
{
- DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl);
g_autoptr(GError) err = NULL;
g_autoptr(GUnixFDList) fd_list = NULL;
int fd;
@@ -322,6 +322,76 @@ static void dbus_scanout_dmabuf(DisplayChangeListener *dcl,
y0_top, G_DBUS_CALL_FLAGS_NONE,
-1, fd_list, NULL, NULL, NULL);
}
+
+static void dbus_scanout_dmabuf_multi_plane(DBusDisplayListener *ddl,
+ QemuDmaBuf *dmabuf)
+{
+ g_autoptr(GError) err = NULL;
+ g_autoptr(GUnixFDList) fd_list = NULL;
+ int i, fd_index[DMABUF_MAX_PLANES], num_fds;
+ uint32_t width, height, fourcc, num_planes;
+ GVariant *fd, *offset, *stride, *fd_handles[DMABUF_MAX_PLANES];
+ uint64_t modifier;
+ bool y0_top;
+
+ num_planes = qemu_dmabuf_get_num_planes(dmabuf);
+
+ fd_list = g_unix_fd_list_new();
+
+ for (num_fds = 0; num_fds < num_planes; num_fds++) {
+ int plane_fd = qemu_dmabuf_get_fd(dmabuf)[num_fds];
+
+ if (plane_fd < 0)
+ break;
+
+ fd_index[num_fds] = g_unix_fd_list_append(fd_list, plane_fd, &err);
+ if (fd_index[num_fds] < 0) {
+ error_report("Failed to setup dmabuf fdlist: %s", err->message);
+ return;
+ }
+ }
+
+ ddl_discard_display_messages(ddl);
+
+ width = qemu_dmabuf_get_width(dmabuf);
+ height = qemu_dmabuf_get_height(dmabuf);
+ fourcc = qemu_dmabuf_get_fourcc(dmabuf);
+ modifier = qemu_dmabuf_get_modifier(dmabuf);
+ y0_top = qemu_dmabuf_get_y0_top(dmabuf);
+
+ offset = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
+ qemu_dmabuf_get_offset(dmabuf),
+ num_planes, sizeof(uint32_t));
+ stride = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
+ qemu_dmabuf_get_stride(dmabuf),
+ num_planes, sizeof(uint32_t));
+
+ for (i = 0; i < num_fds; i++) {
+ fd_handles[i] = g_variant_new_handle(fd_index[i]);
+ }
+ fd = g_variant_new_array(G_VARIANT_TYPE_HANDLE, fd_handles, num_fds);
+
+ qemu_dbus_display1_listener_unix_multi_plane_call_scanout_dmabuf2(
+ ddl->multi_plane_proxy, fd, width, height, offset, stride, num_planes,
+ fourcc, modifier, y0_top, G_DBUS_CALL_FLAGS_NONE,
+ -1, fd_list, NULL, NULL, NULL);
+}
+
+static void dbus_scanout_dmabuf(DisplayChangeListener *dcl,
+ QemuDmaBuf *dmabuf)
+{
+ DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl);
+
+ if (ddl->multi_plane_proxy) {
+ dbus_scanout_dmabuf_multi_plane(ddl, dmabuf);
+ } else {
+ if (qemu_dmabuf_get_num_planes(dmabuf) > 1) {
+ g_debug("org.qemu.Display1.Listener.ScanoutDMABUF does not support mutli plane");
+ return;
+ }
+ dbus_scanout_dmabuf_single_plane(ddl, dmabuf);
+ }
+}
#endif /* GBM */
#endif /* OPENGL */
@@ -514,10 +584,6 @@ static void dbus_scanout_texture(DisplayChangeListener *dcl,
error_report("%s: failed to export dmabuf for texture", __func__);
return;
}
- if (num_planes > 1) {
- error_report("%s: does not support multi-plane dmabuf", __func__);
- return;
- }
dmabuf = qemu_dmabuf_new(w, h, offset, stride, x, y, backing_width,
backing_height, fourcc, modifier, fd, num_planes,
false, backing_y_0_top);
@@ -886,6 +952,8 @@ dbus_display_listener_dispose(GObject *object)
#ifdef CONFIG_OPENGL
egl_fb_destroy(&ddl->fb);
#endif
+#else /* !WIN32 */
+ g_clear_object(&ddl->multi_plane_proxy);
#endif
G_OBJECT_CLASS(dbus_display_listener_parent_class)->dispose(object);
@@ -1074,6 +1142,26 @@ dbus_display_listener_setup_shared_map(DBusDisplayListener *ddl)
#endif
}
+static void dbus_display_listener_setup_multi_plane(DBusDisplayListener *ddl)
+{
+#ifndef WIN32
+ g_autoptr(GError) err = NULL;
+
+ if (!dbus_display_listener_implements(
+ ddl, "org.qemu.Display1.Listener.Unix.MultiPlane")) {
+ return;
+ }
+ ddl->multi_plane_proxy =
+ qemu_dbus_display1_listener_unix_multi_plane_proxy_new_sync(
+ ddl->conn, G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, NULL,
+ "/org/qemu/Display1/Listener", NULL, &err);
+ if (!ddl->multi_plane_proxy) {
+ g_debug("Failed to setup Unix multi plane proxy: %s", err->message);
+ return;
+ }
+#endif
+}
+
static GDBusMessage *
dbus_filter(GDBusConnection *connection,
GDBusMessage *message,
@@ -1162,6 +1250,7 @@ dbus_display_listener_new(const char *bus_name,
dbus_display_listener_setup_shared_map(ddl);
trace_dbus_can_share_map(ddl->can_share_map);
dbus_display_listener_setup_d3d11(ddl);
+ dbus_display_listener_setup_multi_plane(ddl);
con = qemu_console_lookup_by_index(dbus_display_console_get_index(console));
assert(con);
--
2.43.0
next prev parent reply other threads:[~2025-03-24 8:21 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-24 8:19 [PATCH 0/6] ui: support multi plane texture yuq825
2025-03-24 8:19 ` [PATCH 1/6] ui/dmabuf: extend QemuDmaBuf to support multi-plane yuq825
2025-03-24 10:04 ` Marc-André Lureau
2025-03-24 13:16 ` Qiang Yu
2025-03-24 14:06 ` Marc-André Lureau
2025-03-25 3:26 ` Qiang Yu
2025-03-25 6:37 ` Marc-André Lureau
2025-03-25 6:52 ` Qiang Yu
2025-03-25 7:22 ` Marc-André Lureau
2025-03-24 8:19 ` [PATCH 2/6] ui/egl: require EGL_EXT_image_dma_buf_import_modifiers yuq825
2025-03-24 10:09 ` Marc-André Lureau
2025-03-24 13:22 ` Qiang Yu
2025-03-24 13:45 ` Marc-André Lureau
2025-03-25 3:16 ` Qiang Yu
2025-03-24 8:19 ` [PATCH 3/6] ui/egl: use DRM_FORMAT_MOD_INVALID as default modifier yuq825
2025-03-24 10:15 ` Marc-André Lureau
2025-03-24 8:19 ` [PATCH 4/6] ui/egl: support multi-plane dmabuf when egl export/import yuq825
2025-03-24 8:19 ` yuq825 [this message]
2025-03-24 8:19 ` [PATCH 6/6] ui/spice: support multi plane dmabuf scanout yuq825
2025-03-24 9:30 ` Marc-André Lureau
2025-03-24 10:00 ` Daniel P. Berrangé
2025-03-24 13:35 ` Qiang Yu
2025-03-24 14:02 ` Marc-André Lureau
2025-03-26 1:45 ` Qiang Yu
2025-03-26 6:38 ` Marc-André Lureau
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250324081922.359369-6-yuq825@gmail.com \
--to=yuq825@gmail.com \
--cc=marcandre.lureau@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.