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 */