virtio-gpu: replace the surface with null surface when resetting

The primary guest scanout shows the booting screen right after reboot
but additional guest displays (i.e. max_ouptuts > 1) will keep displaying
the old frames until the guest virtio gpu driver gets initialized, which
could cause some confusion. A better way is to to replace the surface with
a place holder that tells the display is not active during the reset of
virtio-gpu device.

And to immediately update the surface with the place holder image after
the switch, displaychangelistener_gfx_switch needs to be called with
'update == TRUE' in dpy_gfx_replace_surface when the new surface is NULL.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Cc: Vivek Kasireddy <vivek.kasireddy@intel.com>
Signed-off-by: Dongwon Kim <dongwon.kim@intel.com>
Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <20230627224451.11739-1-dongwon.kim@intel.com>
This commit is contained in:
Dongwon Kim 2023-06-27 15:44:51 -07:00 committed by Marc-André Lureau
parent 83b4b236ed
commit 0d0be87659
2 changed files with 11 additions and 5 deletions

View file

@ -1898,6 +1898,7 @@ void dpy_gfx_replace_surface(QemuConsole *con,
static const char placeholder_msg[] = "Display output is not active.";
DisplayState *s = con->ds;
DisplaySurface *old_surface = con->surface;
DisplaySurface *new_surface = surface;
DisplayChangeListener *dcl;
int width;
int height;
@ -1911,19 +1912,19 @@ void dpy_gfx_replace_surface(QemuConsole *con,
height = 480;
}
surface = qemu_create_placeholder_surface(width, height, placeholder_msg);
new_surface = qemu_create_placeholder_surface(width, height, placeholder_msg);
}
assert(old_surface != surface);
assert(old_surface != new_surface);
con->scanout.kind = SCANOUT_SURFACE;
con->surface = surface;
dpy_gfx_create_texture(con, surface);
con->surface = new_surface;
dpy_gfx_create_texture(con, new_surface);
QLIST_FOREACH(dcl, &s->listeners, next) {
if (con != (dcl->con ? dcl->con : active_console)) {
continue;
}
displaychangelistener_gfx_switch(dcl, surface, FALSE);
displaychangelistener_gfx_switch(dcl, new_surface, surface ? FALSE : TRUE);
}
dpy_gfx_destroy_texture(con, old_surface);
qemu_free_displaysurface(old_surface);