On 2026/09/04 22:10, Marc-André Lureau wrote:
Use the common virtio_gpu_disable_scanout() to reset the scanout state,
including GL state if any.

Fixes: 7c092f17ccee ("virtio-gpu: Handle resource blob commands")
Signed-off-by: Marc-André Lureau <[email protected]>
---
  hw/display/virtio-gpu-rutabaga.c | 4 +---
  hw/display/virtio-gpu-virgl.c    | 6 ++----
  hw/display/virtio-gpu.c          | 7 +++++--
  3 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/hw/display/virtio-gpu-rutabaga.c b/hw/display/virtio-gpu-rutabaga.c
index 8a82e96b7461..8697dd6936ba 100644
--- a/hw/display/virtio-gpu-rutabaga.c
+++ b/hw/display/virtio-gpu-rutabaga.c
@@ -312,9 +312,7 @@ rutabaga_cmd_set_scanout(VirtIOGPU *g, struct 
virtio_gpu_ctrl_command *cmd)
      scanout = &vb->scanout[ss.scanout_id];
if (ss.resource_id == 0) {
-        scanout->resource_id = 0;
-        qemu_console_set_surface(scanout->con, NULL);
-        qemu_console_gl_scanout_disable(scanout->con);
+        virtio_gpu_disable_scanout(g, ss.scanout_id);
          return;
      }
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 79d4c0b569fb..87d1fc3d5f65 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -618,8 +618,7 @@ static void virgl_cmd_set_scanout(VirtIOGPU *g,
              ss.r.x, ss.r.y, ss.r.width, ss.r.height,
              d3d_tex2d);
      } else {
-        qemu_console_set_surface(g->parent_obj.scanout[ss.scanout_id].con, 
NULL);
-        
qemu_console_gl_scanout_disable(g->parent_obj.scanout[ss.scanout_id].con);
+        virtio_gpu_disable_scanout(g, ss.scanout_id);
      }
      g->parent_obj.scanout[ss.scanout_id].resource_id = ss.resource_id;
  }
@@ -1426,8 +1425,7 @@ void virtio_gpu_virgl_reset_scanout(VirtIOGPU *g)
      int i;
for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
-        qemu_console_set_surface(g->parent_obj.scanout[i].con, NULL);
-        qemu_console_gl_scanout_disable(g->parent_obj.scanout[i].con);
+        virtio_gpu_disable_scanout(g, i);
      }
  }
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index ae1f87ad68b2..cb096cb349cd 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -435,8 +435,11 @@ void virtio_gpu_disable_scanout(VirtIOGPU *g, int 
scanout_id)
  {
      struct virtio_gpu_scanout *scanout = &g->parent_obj.scanout[scanout_id];
- virtio_gpu_release_scanout_dmabuf(g, scanout_id);
-
+    if (scanout->dmabuf) {
+        virtio_gpu_release_scanout_dmabuf(g, scanout_id);
+    } else {
+        qemu_console_gl_scanout_disable(scanout->con);
+    }

GL needs to be always disabled when clearing a scanout.

Having scanout->dmabuf suppresses the explicit GL-disable callback. This misses a real reset path:
1. Reset a Virgl device displaying a hostmem-mapped blob.
2. virtio_gpu_virgl_resource_unref() starts asynchronous unmapping and
   returns before disabling its scanouts.
3. virtio_gpu_reset_bh() installs placeholder surfaces, changing the
   console to SCANOUT_SURFACE; virtio_gpu_base_reset() clears the
   resource IDs.
4. virtio_gpu_gl_reset() calls virtio_gpu_virgl_reset_scanout(). The new
   helper releases the retained DMA-BUF, but
   qemu_console_gl_release_dmabuf() invokes GL-disable only for
   SCANOUT_DMABUF.
5. GTK’s release callback clears the DMA-BUF pointer but leaves
   scanout_mode and its framebuffer. The queued redraw continues through
   the old framebuffer path instead of displaying the placeholder, blit
   in gd_gl_area_draw().

Before this patch, virtio_gpu_virgl_reset_scanout() always called GL-disable. Please ensure the disable helper actually disables the frontend even when releasing a wrapper whose console has already switched to a surface.

Regards,
Akihiko Odaki

      qemu_console_set_surface(scanout->con, NULL);
      scanout->resource_id = 0;
      scanout->ds = NULL;



Reply via email to