xserver: Branch 'master' - 3 commits

Adam Jackson ajax at kemper.freedesktop.org
Mon Dec 7 11:40:07 PST 2015


 present/present.c      |   47 ++++++++++++++++++++++++++++++++++++-----------
 present/present_priv.h |    2 ++
 2 files changed, 38 insertions(+), 11 deletions(-)

New commits:
commit 72f0724cdc65dc9abbbf70b9feb6cce7c2b9f8a0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Feb 8 09:47:42 2015 +0000

    present: Do not replace Pixmaps on redirected Window on unflip
    
    When unflipping, we may find that our flip window has been redirected.
    If we replace the redirected Window with the Screen Pixmap we then have
    mutliple fullscreen Windows believing that their own the Screen Pixmap -
    multiple fullscreen Windows that are being flipped by Clients, and so
    continue to flip causing popping between e.g. the compositor and the
    game.
    
    [ajax: Fix up present_execute() hunk to account for changes introduced
    in fe07ec19e212a68076560d243a2a935c54589068]
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/present/present.c b/present/present.c
index c55a56e..66e0f21 100644
--- a/present/present.c
+++ b/present/present.c
@@ -374,12 +374,17 @@ present_set_tree_pixmap_visit(WindowPtr window, void *data)
 }
 
 static void
-present_set_tree_pixmap(WindowPtr window, PixmapPtr pixmap)
+present_set_tree_pixmap(WindowPtr window,
+                        PixmapPtr expected,
+                        PixmapPtr pixmap)
 {
     struct pixmap_visit visit;
     ScreenPtr           screen = window->drawable.pScreen;
 
     visit.old = (*screen->GetWindowPixmap)(window);
+    if (expected && visit.old != expected)
+        return;
+
     visit.new = pixmap;
     if (visit.old == visit.new)
         return;
@@ -390,6 +395,7 @@ static void
 present_set_abort_flip(ScreenPtr screen)
 {
     present_screen_priv_ptr screen_priv = present_screen_priv(screen);
+    PixmapPtr pixmap = (*screen->GetScreenPixmap)(screen);
 
     /* Switch back to using the screen pixmap now to avoid
      * 2D applications drawing to the wrong pixmap.
@@ -397,10 +403,11 @@ present_set_abort_flip(ScreenPtr screen)
 
     if (screen_priv->flip_window)
         present_set_tree_pixmap(screen_priv->flip_window,
-                                  (*screen->GetScreenPixmap)(screen));
+                                screen_priv->flip_pixmap,
+                                pixmap);
 
     if (screen->root)
-        present_set_tree_pixmap(screen->root, (*screen->GetScreenPixmap)(screen));
+        present_set_tree_pixmap(screen->root, NULL, pixmap);
 
     screen_priv->flip_pending->abort_flip = TRUE;
 }
@@ -414,10 +421,12 @@ present_unflip(ScreenPtr screen)
     assert (!screen_priv->unflip_event_id);
     assert (!screen_priv->flip_pending);
 
-    if (screen_priv->flip_window)
-        present_set_tree_pixmap(screen_priv->flip_window, pixmap);
+    if (screen_priv->flip_pixmap && screen_priv->flip_window)
+        present_set_tree_pixmap(screen_priv->flip_window,
+                                screen_priv->flip_pixmap,
+                                pixmap);
 
-    present_set_tree_pixmap(screen->root, pixmap);
+    present_set_tree_pixmap(screen->root, NULL, pixmap);
 
     /* Update the screen pixmap with the current flip pixmap contents
      */
@@ -644,9 +653,10 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
                  */
                 if (screen_priv->flip_window && screen_priv->flip_window != window)
                     present_set_tree_pixmap(screen_priv->flip_window,
-                                              (*screen->GetScreenPixmap)(screen));
-                present_set_tree_pixmap(vblank->window, vblank->pixmap);
-                present_set_tree_pixmap(screen->root, vblank->pixmap);
+                                            screen_priv->flip_pixmap,
+                                            (*screen->GetScreenPixmap)(screen));
+                present_set_tree_pixmap(vblank->window, NULL, vblank->pixmap);
+                present_set_tree_pixmap(screen->root, NULL, vblank->pixmap);
 
                 /* Report update region as damaged
                  */
commit 180b09912c0d2c4a43b5a08678bcad4b818924c7
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Feb 8 09:47:41 2015 +0000

    present: When cancelling a pending synchronous flip, requeue it
    
    The vblank event request for a synchronous flip is scheduled for the
    vblank before the target flip msc (so that the flip itself appears at
    the right frame). If we cancel that flip and so wish to schedule a
    copy instead, that copy needs to be postponed by a frame in order for it
    be performed at the requested time.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/present/present.c b/present/present.c
index 7af6bb7..c55a56e 100644
--- a/present/present.c
+++ b/present/present.c
@@ -549,8 +549,13 @@ present_check_flip_window (WindowPtr window)
 
     /* Now check any queued vblanks */
     xorg_list_for_each_entry(vblank, &window_priv->vblank, window_list) {
-        if (vblank->queued && vblank->flip && !present_check_flip(vblank->crtc, window, vblank->pixmap, vblank->sync_flip, NULL, 0, 0))
+        if (vblank->queued && vblank->flip && !present_check_flip(vblank->crtc, window, vblank->pixmap, vblank->sync_flip, NULL, 0, 0)) {
             vblank->flip = FALSE;
+            if (vblank->sync_flip) {
+                vblank->requeue = TRUE;
+                vblank->target_msc++;
+            }
+        }
     }
 }
 
@@ -584,6 +589,15 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
     present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
     uint8_t                     mode;
 
+    if (vblank->requeue) {
+        vblank->requeue = FALSE;
+        if (Success == present_queue_vblank(screen,
+                                            vblank->crtc,
+                                            vblank->event_id,
+                                            vblank->target_msc))
+            return;
+    }
+
     if (vblank->wait_fence) {
         if (!present_fence_check_triggered(vblank->wait_fence)) {
             present_fence_set_callback(vblank->wait_fence, present_wait_fence_triggered, vblank);
diff --git a/present/present_priv.h b/present/present_priv.h
index d007fdb..0d16cfa 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -70,6 +70,7 @@ struct present_vblank {
     present_notify_ptr  notifies;
     int                 num_notifies;
     Bool                queued;         /* on present_exec_queue */
+    Bool                requeue;        /* on queue, but target_msc has changed */
     Bool                flip;           /* planning on using flip */
     Bool                flip_ready;     /* wants to flip, but waiting for previous flip or unflip */
     Bool                sync_flip;      /* do flip synchronous to vblank */
commit b2d55338f6b8f43ebcb49994abad123a797248cf
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Feb 8 09:47:40 2015 +0000

    present: Requery pending flips with the right sync_flip mode
    
    When verifying whether a pending flip is still valid, we need to pass
    down the orignal sync_flip mode (e.g. if the driver only supports sync
    flips, verifying a async flip will falsely fail).
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/present/present.c b/present/present.c
index beb01dc..7af6bb7 100644
--- a/present/present.c
+++ b/present/present.c
@@ -453,6 +453,7 @@ present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
     screen_priv->flip_window = vblank->window;
     screen_priv->flip_serial = vblank->serial;
     screen_priv->flip_pixmap = vblank->pixmap;
+    screen_priv->flip_sync = vblank->sync_flip;
     screen_priv->flip_idle_fence = vblank->idle_fence;
 
     vblank->pixmap = NULL;
@@ -541,14 +542,14 @@ present_check_flip_window (WindowPtr window)
          * Check current flip
          */
         if (window == screen_priv->flip_window) {
-            if (!present_check_flip(screen_priv->flip_crtc, window, screen_priv->flip_pixmap, FALSE, NULL, 0, 0))
+            if (!present_check_flip(screen_priv->flip_crtc, window, screen_priv->flip_pixmap, screen_priv->flip_sync, NULL, 0, 0))
                 present_unflip(screen);
         }
     }
 
     /* Now check any queued vblanks */
     xorg_list_for_each_entry(vblank, &window_priv->vblank, window_list) {
-        if (vblank->queued && vblank->flip && !present_check_flip(vblank->crtc, window, vblank->pixmap, FALSE, NULL, 0, 0))
+        if (vblank->queued && vblank->flip && !present_check_flip(vblank->crtc, window, vblank->pixmap, vblank->sync_flip, NULL, 0, 0))
             vblank->flip = FALSE;
     }
 }
diff --git a/present/present_priv.h b/present/present_priv.h
index 996292e..d007fdb 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -93,6 +93,7 @@ typedef struct present_screen_priv {
     uint32_t                    flip_serial;
     PixmapPtr                   flip_pixmap;
     present_fence_ptr           flip_idle_fence;
+    Bool                        flip_sync;
 
     present_screen_info_ptr     info;
 } present_screen_priv_rec, *present_screen_priv_ptr;


More information about the xorg-commit mailing list