On 2026/01/15 17:25, Marc-André Lureau wrote:
Hi Akihiko

On Thu, Jan 15, 2026 at 9:44 AM Akihiko Odaki
<[email protected]> wrote:

ui/gtk performs the following procedure to flush a scanout:
1) Queue a draw event.
2) The draw event gets triggered.
3) Blit the scanout to the framebuffer.

When flushing a DMA-BUF scanout, ui/gtk blocks the device before 2) if
possible and unblocks it after 3).

Blocking the device before 2) has two problems.

First, it can leave the device blocked indefinitely because GTK
sometimes decides to cancel 2) when the window is not visible for
example. ui/gtk regularly repeats 1) as a workaround, but it is not
applicable to GtkGLArea because it causes display corruption.

Second, the behavior is inconsistent with the other types of scanout
that leaves the device unblocked between 1) and 2).

To fix these problems, let ui/gtk block the device after 2) instead.

Wouldn't that let the device overwrite the buffer before it is displayed?

That's correct.

The rationale I wrote in the commit message is that it is a long-standing behavior for the other scanout types.

You can also "infer" this from the fact that the specification mentions pageflip, though it is a convoluted way:

> It is possible to create multiple framebuffers, flip between them
> using VIRTIO_GPU_CMD_SET_SCANOUT and VIRTIO_GPU_CMD_RESOURCE_FLUSH,
> and update the invisible framebuffer using
> VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D.

https://docs.oasis-open.org/virtio/virtio/v1.2/csd01/virtio-v1.2-csd01.html#x1-375001r381

If scanout flush is truly atomic, there is no point of performing pageflip and you can instead simply always use VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D for the visible framebuffer.

So, from the guest perspective, there are two options to implement scanout:

- Do pageflip to avoid tearing at cost of having two framebuffers and
  late display.
- Do not pageflip to avoid having two buffers and display the content
  as soon as possible though it may cause tearing.


I wish there would be a clear design for how virtio-gpu handles
display buffering.. I suppose more demanding users, like crosvm may
have documented this.

Allowing tearing to occur when not doing pageflip is a common sensible design (e.g., EGL: eglSwapInterval() with 0 as the interval parameter, Vulkan: VK_PRESENT_MODE_IMMEDIATE_KHR), though I see other things lacking in the design (e.g., vsync).

crosvm performs no synchronization and prone to tearing if I read it correctly. A code comment says:
> It is possible that we are committing frames faster than the
> compositor can put them on the screen. This may result in dropped
> frames, but this is acceptable considering there is no good way to
> apply back pressure to the guest gpu driver right now. The intention
> of this module is to help bootstrap gpu support, so it does not have
> to have artifact free rendering.

https://chromium.googlesource.com/crosvm/crosvm/+/51cf0f429d64bd24281d9c9920c6712c491b5473/gpu_display/src/display_wl.c#1238

I suppose they care the Wayland passthrough more than the plain scanout mechanism. It will be nice if the specification clearly documents the expected behavior. The current documentation is more like saying "use the common sense and see QEMU if not sure"; it doesn't help much when writing QEMU.

Regards,
Akihiko Odaki

Reply via email to