6c2dd5fc20
The content of this branch was automatically imported from Fedora ELN with the following as its source: https://src.fedoraproject.org/rpms/xorg-x11-server#eaf442296937a83e622ce4995c5f33122bcd6f02
140 lines
5.5 KiB
Diff
140 lines
5.5 KiB
Diff
From c3e4c1a0fd5d4d6015e9e6317b758018317e56d1 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <mdaenzer@redhat.com>
|
|
Date: Tue, 28 Jul 2020 18:40:47 +0200
|
|
Subject: [PATCH xserver 16/16] present/wnmd: Execute copies at target_msc-1
|
|
already
|
|
|
|
It always takes one update cycle for the copy to become visible on the
|
|
host windowing system, so waiting for the target MSC resulted in 1 cycle
|
|
delay.
|
|
|
|
We re-use the idle list for copies which were executed but need their
|
|
completion event sent.
|
|
|
|
Fixes black seams when resizing the "Builder" sub-window of
|
|
|
|
GDK_BACKEND=x11 gtk4-demo
|
|
|
|
on Xwayland (see
|
|
https://gitlab.gnome.org/GNOME/mutter/-/issues/1290#note_873557).
|
|
|
|
Unfortunately, this cannot completely fix the seams with apps which
|
|
queue up multiple frames in advance, since there's always at least one
|
|
queued frame corresponding to the old window size. But it should at
|
|
least help a little in that case as well.
|
|
|
|
v2:
|
|
* Bug fix: Don't update exec_msc in present_wnmd_check_flip_window.
|
|
(Roman Gilg)
|
|
* Use exec_msc = target_msc - 1 instead of exec_msc--, and add a
|
|
comment, for clarity.
|
|
v3:
|
|
* Drop exec_msc = target_msc again in present_wnmd_execute.
|
|
* present_execute_copy should never set vblank->queued in
|
|
present_wnmd_execute now, so replace that branch with an assertion.
|
|
(Roman Gilg)
|
|
|
|
Reviewed-by: Roman Gilg <subdiff@gmail.com>
|
|
Tested-by: Roman Gilg <subdiff@gmail.com>
|
|
(cherry picked from commit 1cccb486d48a5d2e7649836b993805bb65dc09e3)
|
|
[Since present_wnmd_event_notify hasn't been split up on the 1.20
|
|
branch, it needs to check vblank->flip. Doing the same in
|
|
present_wnmd_free_idle_vblanks to be safe, though I'm not sure it's
|
|
actually possible to hit non-flips there.]
|
|
---
|
|
present/present_wnmd.c | 28 ++++++++++++++++++----------
|
|
1 file changed, 18 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/present/present_wnmd.c b/present/present_wnmd.c
|
|
index 2c11e53f5..8c31619a2 100644
|
|
--- a/present/present_wnmd.c
|
|
+++ b/present/present_wnmd.c
|
|
@@ -122,7 +122,8 @@ present_wnmd_free_idle_vblanks(WindowPtr window)
|
|
present_vblank_ptr vblank, tmp;
|
|
|
|
xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->idle_queue, event_queue) {
|
|
- present_wnmd_free_idle_vblank(vblank);
|
|
+ if (vblank->flip)
|
|
+ present_wnmd_free_idle_vblank(vblank);
|
|
}
|
|
|
|
if (window_priv->flip_active) {
|
|
@@ -245,7 +246,12 @@ present_wnmd_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uin
|
|
|
|
xorg_list_for_each_entry(vblank, &window_priv->idle_queue, event_queue) {
|
|
if (vblank->event_id == event_id) {
|
|
- present_wnmd_free_idle_vblank(vblank);
|
|
+ if (vblank->flip)
|
|
+ present_wnmd_free_idle_vblank(vblank);
|
|
+ else
|
|
+ /* Copies which were executed but need their completion event sent */
|
|
+ present_execute_post(vblank, ust, msc);
|
|
+
|
|
return;
|
|
}
|
|
}
|
|
@@ -353,8 +359,6 @@ present_wnmd_check_flip_window (WindowPtr window)
|
|
vblank->sync_flip, vblank->valid, 0, 0, &reason)) {
|
|
vblank->flip = FALSE;
|
|
vblank->reason = reason;
|
|
- if (vblank->sync_flip)
|
|
- vblank->exec_msc = vblank->target_msc;
|
|
}
|
|
}
|
|
}
|
|
@@ -454,6 +458,7 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
|
|
vblank->queued = FALSE;
|
|
|
|
if (vblank->pixmap && vblank->window) {
|
|
+ ScreenPtr screen = window->drawable.pScreen;
|
|
|
|
if (vblank->flip) {
|
|
RegionPtr damage;
|
|
@@ -479,7 +484,6 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
|
|
// ask the driver
|
|
if (present_wnmd_flip(vblank->window, vblank->crtc, vblank->event_id,
|
|
vblank->target_msc, vblank->pixmap, vblank->sync_flip, damage)) {
|
|
- ScreenPtr screen = window->drawable.pScreen;
|
|
WindowPtr toplvl_window = present_wnmd_toplvl_pixmap_window(vblank->window);
|
|
PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
|
|
|
|
@@ -502,7 +506,6 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
|
|
*/
|
|
window_priv->flip_pending = NULL;
|
|
vblank->flip = FALSE;
|
|
- vblank->exec_msc = vblank->target_msc;
|
|
}
|
|
DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
|
|
vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
|
|
@@ -510,9 +513,12 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
|
|
present_wnmd_cancel_flip(window);
|
|
|
|
present_execute_copy(vblank, crtc_msc);
|
|
+ assert(!vblank->queued);
|
|
|
|
- if (vblank->queued) {
|
|
- xorg_list_add(&vblank->event_queue, &window_priv->exec_queue);
|
|
+ if (present_wnmd_queue_vblank(screen, window, vblank->crtc,
|
|
+ vblank->event_id, crtc_msc + 1)
|
|
+ == Success) {
|
|
+ xorg_list_add(&vblank->event_queue, &window_priv->idle_queue);
|
|
xorg_list_append(&vblank->window_list, &window_priv->vblank);
|
|
|
|
return;
|
|
@@ -632,8 +638,10 @@ present_wnmd_pixmap(WindowPtr window,
|
|
if (!vblank)
|
|
return BadAlloc;
|
|
|
|
- if (vblank->flip && vblank->sync_flip)
|
|
- vblank->exec_msc--;
|
|
+ /* WNMD presentations always complete (at least) one frame after they
|
|
+ * are executed
|
|
+ */
|
|
+ vblank->exec_msc = vblank->target_msc - 1;
|
|
|
|
xorg_list_append(&vblank->event_queue, &window_priv->exec_queue);
|
|
vblank->queued = TRUE;
|
|
--
|
|
2.28.0
|
|
|