diff options
Diffstat (limited to 'ui/dbus-listener.c')
| -rw-r--r-- | ui/dbus-listener.c | 75 |
1 files changed, 57 insertions, 18 deletions
diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c index 18f556aa73..4a0a5d78f9 100644 --- a/ui/dbus-listener.c +++ b/ui/dbus-listener.c @@ -83,6 +83,9 @@ struct _DBusDisplayListener { egl_fb fb; #endif #endif + + guint dbus_filter; + guint32 out_serial_to_discard; }; G_DEFINE_TYPE(DBusDisplayListener, dbus_display_listener, G_TYPE_OBJECT) @@ -90,6 +93,12 @@ G_DEFINE_TYPE(DBusDisplayListener, dbus_display_listener, G_TYPE_OBJECT) static void dbus_gfx_update(DisplayChangeListener *dcl, int x, int y, int w, int h); +static void ddl_discard_pending_messages(DBusDisplayListener *ddl) +{ + ddl->out_serial_to_discard = g_dbus_connection_get_last_serial( + g_dbus_proxy_get_connection(G_DBUS_PROXY(ddl->proxy))); +} + #ifdef CONFIG_OPENGL static void dbus_scanout_disable(DisplayChangeListener *dcl) { @@ -276,6 +285,8 @@ static void dbus_scanout_dmabuf(DisplayChangeListener *dcl, return; } + ddl_discard_pending_messages(ddl); + /* FIXME: add missing x/y/w/h support */ qemu_dbus_display1_listener_call_scanout_dmabuf( ddl->proxy, @@ -323,6 +334,8 @@ static bool dbus_scanout_map(DBusDisplayListener *ddl) return false; } + ddl_discard_pending_messages(ddl); + if (!qemu_dbus_display1_listener_win32_map_call_scanout_map_sync( ddl->map_proxy, GPOINTER_TO_UINT(target_handle), @@ -384,6 +397,8 @@ dbus_scanout_share_d3d_texture( return false; } + ddl_discard_pending_messages(ddl); + qemu_dbus_display1_listener_win32_d3d11_call_scanout_texture2d( ddl->d3d11_proxy, GPOINTER_TO_INT(target_handle), @@ -630,11 +645,28 @@ static void dbus_gfx_update_sub(DBusDisplayListener *ddl, DBUS_DEFAULT_TIMEOUT, NULL, NULL, NULL); } +static void ddl_scanout(DBusDisplayListener *ddl) +{ + GVariant *v_data; + + v_data = g_variant_new_from_data( + G_VARIANT_TYPE("ay"), surface_data(ddl->ds), + surface_stride(ddl->ds) * surface_height(ddl->ds), TRUE, + (GDestroyNotify)pixman_image_unref, pixman_image_ref(ddl->ds->image)); + + ddl_discard_pending_messages(ddl); + + qemu_dbus_display1_listener_call_scanout( + ddl->proxy, surface_width(ddl->ds), surface_height(ddl->ds), + surface_stride(ddl->ds), surface_format(ddl->ds), v_data, + G_DBUS_CALL_FLAGS_NONE, DBUS_DEFAULT_TIMEOUT, NULL, NULL, + g_object_ref(ddl)); +} + static void dbus_gfx_update(DisplayChangeListener *dcl, int x, int y, int w, int h) { DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl); - GVariant *v_data; assert(ddl->ds); @@ -652,23 +684,7 @@ static void dbus_gfx_update(DisplayChangeListener *dcl, #endif if (x == 0 && y == 0 && w == surface_width(ddl->ds) && h == surface_height(ddl->ds)) { - v_data = g_variant_new_from_data( - G_VARIANT_TYPE("ay"), - surface_data(ddl->ds), - surface_stride(ddl->ds) * surface_height(ddl->ds), - TRUE, - (GDestroyNotify)pixman_image_unref, - pixman_image_ref(ddl->ds->image)); - qemu_dbus_display1_listener_call_scanout( - ddl->proxy, - surface_width(ddl->ds), - surface_height(ddl->ds), - surface_stride(ddl->ds), - surface_format(ddl->ds), - v_data, - G_DBUS_CALL_FLAGS_NONE, - DBUS_DEFAULT_TIMEOUT, NULL, NULL, NULL); - return; + return ddl_scanout(ddl); } dbus_gfx_update_sub(ddl, x, y, w, h); @@ -964,6 +980,28 @@ dbus_display_listener_setup_shared_map(DBusDisplayListener *ddl) #endif } +static GDBusMessage * +dbus_filter(GDBusConnection *connection, + GDBusMessage *message, + gboolean incoming, + gpointer user_data) +{ + DBusDisplayListener *ddl = DBUS_DISPLAY_LISTENER(user_data); + guint32 serial; + + if (incoming) { + return message; + } + + serial = g_dbus_message_get_serial(message); + if (serial <= ddl->out_serial_to_discard) { + trace_dbus_filter(serial, ddl->out_serial_to_discard); + return NULL; + } + + return message; +} + DBusDisplayListener * dbus_display_listener_new(const char *bus_name, GDBusConnection *conn, @@ -988,6 +1026,7 @@ dbus_display_listener_new(const char *bus_name, return NULL; } + ddl->dbus_filter = g_dbus_connection_add_filter(conn, dbus_filter, g_object_ref(ddl), g_object_unref); ddl->bus_name = g_strdup(bus_name); ddl->conn = conn; ddl->console = console; |