On 2026/08/25 19:20, Marc-André Lureau wrote:
Narrows release_dmabuf to the active scanout, as the device & console
may interleave new scanouts before releasing old ones.


My AI agent is so nitpicking about the lack of Fixes: tags and its suggestions look reasonable, so I'm leaving them as comments. For this patch:

Fixes: 142ca628a733 ("ui: add a D-Bus display backend")

Regards,
Akihiko Odaki

Signed-off-by: Marc-André Lureau <[email protected]>
---
  ui/dbus-listener.c | 68 ++++++++++++++++++++++++++++++++++++++----------------
  1 file changed, 48 insertions(+), 20 deletions(-)

diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c
index 2e2f6ba4183a..5a72c7eeae59 100644
--- a/ui/dbus-listener.c
+++ b/ui/dbus-listener.c
@@ -91,6 +91,8 @@ struct _DBusDisplayListener {
      guint dbus_filter;
      guint32 display_serial_to_discard;
      guint32 cursor_serial_to_discard;
+
+    QemuDmaBuf *scanout_dmabuf;
  };
G_DEFINE_TYPE(DBusDisplayListener, dbus_display_listener, G_TYPE_OBJECT)
@@ -119,6 +121,7 @@ static void dbus_scanout_disable(DisplayChangeListener *dcl)
  {
      DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl);
+ ddl->scanout_dmabuf = NULL;
      ddl_discard_display_messages(ddl);
qemu_dbus_display1_listener_call_disable(
@@ -298,9 +301,9 @@ static void dbus_call_update_gl(DisplayChangeListener *dcl,
#ifdef CONFIG_GBM
  static void dbus_scanout_dmabuf_v1(DBusDisplayListener *ddl,
-                                   QemuDmaBuf *dmabuf)
+                                   QemuDmaBuf *dmabuf,
+                                   GError **err)
  {
-    g_autoptr(GError) err = NULL;
      g_autoptr(GUnixFDList) fd_list = NULL;
      int fd;
      uint32_t width, height, stride, fourcc;
@@ -309,8 +312,7 @@ static void dbus_scanout_dmabuf_v1(DBusDisplayListener *ddl,
fd = qemu_dmabuf_get_fds(dmabuf, NULL)[0];
      fd_list = g_unix_fd_list_new();
-    if (g_unix_fd_list_append(fd_list, fd, &err) != 0) {
-        error_report("Failed to setup dmabuf fdlist: %s", err->message);
+    if (g_unix_fd_list_append(fd_list, fd, err) != 0) {
          return;
      }
@@ -332,9 +334,9 @@ static void dbus_scanout_dmabuf_v1(DBusDisplayListener *ddl,
  }
static void dbus_scanout_dmabuf_v2(DBusDisplayListener *ddl,
-                                   QemuDmaBuf *dmabuf)
+                                   QemuDmaBuf *dmabuf,
+                                   GError **err)
  {
-    g_autoptr(GError) err = NULL;
      g_autoptr(GUnixFDList) fd_list = NULL;
      int i, fd_index[DMABUF_MAX_PLANES], num_fds;
      uint32_t x, y, width, height, fourcc, backing_width, backing_height;
@@ -360,9 +362,8 @@ static void dbus_scanout_dmabuf_v2(DBusDisplayListener *ddl,
              break;
          }
- fd_index[num_fds] = g_unix_fd_list_append(fd_list, plane_fd, &err);
+        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;
          }
      }
@@ -395,20 +396,36 @@ static void dbus_scanout_dmabuf_v2(DBusDisplayListener 
*ddl,
          G_DBUS_CALL_FLAGS_NONE, -1, fd_list, NULL, NULL, NULL);
  }
+static bool dbus_call_scanout_dmabuf(DBusDisplayListener *ddl,
+                                     QemuDmaBuf *dmabuf)
+{
+    g_autoptr(GError) err = NULL;
+
+    if (ddl->scanout_dmabuf_v2_proxy) {
+        dbus_scanout_dmabuf_v2(ddl, dmabuf, &err);
+    } else {
+        if (qemu_dmabuf_get_num_planes(dmabuf) > 1) {
+            error_report("Peer does not support multi plane dmabuf");
+            return false;
+        }
+        dbus_scanout_dmabuf_v1(ddl, dmabuf, &err);
+    }
+
+    if (err) {
+        error_report("Failed to scanout dmabuf: %s", err->message);
+        return false;
+    }
+
+    return true;
+}
+
  static void dbus_scanout_dmabuf(DisplayChangeListener *dcl,
                                  QemuDmaBuf *dmabuf)
  {
      DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl);
- if (ddl->scanout_dmabuf_v2_proxy) {
-        dbus_scanout_dmabuf_v2(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_v1(ddl, dmabuf);
+    if (dbus_call_scanout_dmabuf(ddl, dmabuf)) {
+        ddl->scanout_dmabuf = dmabuf;
      }
  }
  #endif /* GBM */
@@ -589,6 +606,10 @@ static void dbus_scanout_texture(DisplayChangeListener 
*dcl,
                                   uint32_t w, uint32_t h,
                                   void *d3d_tex2d)
  {
+#if defined(CONFIG_GBM) || defined(WIN32)
+    DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl);
+#endif
+
      trace_dbus_scanout_texture(tex_id, backing_y_0_top,
                                 backing_width, backing_height, x, y, w, h);
  #ifdef CONFIG_GBM
@@ -607,13 +628,13 @@ static void dbus_scanout_texture(DisplayChangeListener 
*dcl,
                               backing_height, fourcc, modifier, fd, num_planes,
                               false, backing_y_0_top);
- dbus_scanout_dmabuf(dcl, dmabuf);
+    if (dbus_call_scanout_dmabuf(ddl, dmabuf)) {
+        ddl->scanout_dmabuf = NULL;
+    }
      qemu_dmabuf_close(dmabuf);
  #endif
#ifdef WIN32
-    DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl);
-
      /* there must be a matching gfx_switch before */
      assert(surface_width(ddl->ds) == w);
      assert(surface_height(ddl->ds) == h);
@@ -686,7 +707,14 @@ static void dbus_cursor_dmabuf(DisplayChangeListener *dcl,
  static void dbus_release_dmabuf(DisplayChangeListener *dcl,
                                  QemuDmaBuf *dmabuf)
  {
+    DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl);
+
+    if (ddl->scanout_dmabuf != dmabuf) {
+        return;
+    }
+
      dbus_scanout_disable(dcl);
+    ddl->scanout_dmabuf = NULL;
  }
  #endif /* GBM */


Reply via email to