From 69871920a5fe55675da1996c27b4bbf7d5840929 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Thu, 30 Oct 2025 15:59:39 +0800 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: a94dd9536 ("modesetting: add support for TearFree page flips") Reviewed-by: Sultan Alsawaf --- hw/xfree86/drivers/modesetting/present.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/xfree86/drivers/modesetting/present.c b/hw/xfree86/drivers/modesetting/present.c index 421d70016..a876a031e 100644 --- a/hw/xfree86/drivers/modesetting/present.c +++ b/hw/xfree86/drivers/modesetting/present.c @@ -322,6 +322,9 @@ ms_present_check_flip(RRCrtcPtr crtc, ScrnInfoPtr scrn = xf86ScreenToScrn(screen); modesettingPtr ms = modesettingPTR(scrn); + if (reason) + *reason = PRESENT_FLIP_REASON_UNKNOWN; + if (ms->drmmode.sprites_visible > 0) goto no_flip; @@ -337,7 +340,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;