[PATCH xserver 1/3] present: Only update screen pixmap from flip pixmap once per unflip

Michel Dänzer michel at daenzer.net
Fri Feb 19 02:39:10 UTC 2016

From: Michel Dänzer <michel.daenzer at amd.com>

present_unflip may be called several times from present_check_flip_window
during the same unflip. We can only copy to the screen pixmap the first
time, otherwise we may scribble over other windows. The flip pixmap
contents don't get updated after the first time anyway.

Fixes at least the following problems, which were introduced by commit
806470b9 ("present: Copy unflip contents back to the Screen Pixmap"):

On xfwm4 without compositing, run glxgears and put its window into
fullscreen mode to start flipping. While in fullscreen, open the xfwm4
window menu by pressing Alt-Space. The window menu was invisible most
of the time because it was getting scribbled over by a repeated unflip

When switching a flipping window out of fullscreen, a repeated unflip
copy could leave artifacts of the flip pixmap on the desktop.

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
 present/present.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/present/present.c b/present/present.c
index 8cf3b6f..d6ec895 100644
--- a/present/present.c
+++ b/present/present.c
@@ -421,6 +421,15 @@ present_unflip(ScreenPtr screen)
     assert (!screen_priv->unflip_event_id);
     assert (!screen_priv->flip_pending);
+    /* Update the screen pixmap with the current flip pixmap contents
+     * Only do this the first time for a particular unflip operation, or
+     * we'll probably scribble over other windows
+     */
+    if (screen->GetWindowPixmap(screen->root) == screen_priv->flip_pixmap) {
+        present_copy_region(&pixmap->drawable, screen_priv->flip_pixmap,
+                            NULL, 0, 0);
+    }
     if (screen_priv->flip_pixmap && screen_priv->flip_window)
@@ -428,13 +437,6 @@ present_unflip(ScreenPtr screen)
     present_set_tree_pixmap(screen->root, NULL, pixmap);
-    /* Update the screen pixmap with the current flip pixmap contents
-     */
-    if (screen_priv->flip_pixmap && screen_priv->flip_window) {
-        present_copy_region(&pixmap->drawable,
-                            screen_priv->flip_pixmap,
-                            NULL, 0, 0);
-    }
     screen_priv->unflip_event_id = ++present_event_id;
     DebugPresent(("u %lld\n", screen_priv->unflip_event_id));
     (*screen_priv->info->unflip) (screen, screen_priv->unflip_event_id);

More information about the xorg-devel mailing list