From c5fad50afec124b625539f8c84ba92ef93e2fcd4 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Wed, 5 Nov 2025 11:52:57 +0100 Subject: [PATCH] modesetting: fix PRESENT_FLIP_REASON_BUFFER_FORMAT gets overwritten When dmabuf_capable is enabled, ms_present_check_unflip may return with reason PRESENT_FLIP_REASON_BUFFER_FORMAT to be reported back to client by PresentCompleteModeSuboptimalCopy. We should not overwrite it by page flip reasons anyway when exit. This fix also avoid changing vblank->exec_msc in present_scmd_pixmap() which caused by page flip reasons to prevent a present to be executed immediatly. So that we can cancel pending vblanks when new vblanks with same msc arrive. This happens when application just starts. This problem can be observed at least using radeonsi OGL driver, start xserver with dmabuf_capable enabled, no window manager, glxgears will stuck for the first several seconds. If using a composite window manager like Mutter, we can't observe the glxgears stuck, but the prensent complete event still shows unexpected Copy mode instead of PresentCompleteModeSuboptimalCopy or Skip mode. glxgears window msc is 0 at the beginning, it will send present request with target msc = 1, 2, 3, ... N before server send back the complete event for target msc = 1. But server side window msc is way bigger than N, so it will think all these present requests are outdated and just show the Nth request at the next vblank. [1 .. N-1] requests should be skipped. But without this fix, all [1 .. N] presents will be executed with Copy mode which causes stuck. Fixes: a94dd953 ("modesetting: add support for TearFree page flips") --- hw/xfree86/drivers/video/modesetting/present.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xfree86/drivers/video/modesetting/present.c b/hw/xfree86/drivers/video/modesetting/present.c index 80ac5c9d3d..87cde09f0b 100644 --- a/hw/xfree86/drivers/video/modesetting/present.c +++ b/hw/xfree86/drivers/video/modesetting/present.c @@ -352,7 +352,7 @@ ms_present_check_flip(RRCrtcPtr crtc, no_flip: /* Export some info about TearFree if Present can't flip anyway */ - if (reason) { + if (reason && *reason == PRESENT_FLIP_REASON_UNKNOWN) { xf86CrtcPtr xf86_crtc = crtc->devPrivate; drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; drmmode_tearfree_ptr trf = &drmmode_crtc->tearfree;