xserver: Branch 'master' - 5 commits

Keith Packard keithp at kemper.freedesktop.org
Wed Nov 20 13:13:02 PST 2013


 present/present.c        |   52 ++++++++++++++++++++++++++++++++++++++---------
 present/present_event.c  |    2 -
 present/present_fake.c   |    2 -
 present/present_fence.c  |   29 +++++++++++++++++++++++++-
 present/present_priv.h   |   17 +++++++++++++--
 present/present_screen.c |    2 -
 6 files changed, 88 insertions(+), 16 deletions(-)

New commits:
commit 6403cbb143c67872ca9c58e3116ae7942def0ae1
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Nov 19 22:13:54 2013 -0800

    present: When unflipping, copy to flip window rather than screen
    
    unflip happens after the clip lists have been updated, so instead of
    smashing the whole screen and drawing over other windows, just draw to
    the original flip window; it'll have the right clip list and so the
    copy will work just fine.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/present/present.c b/present/present.c
index 16dc381..f9eef6b 100644
--- a/present/present.c
+++ b/present/present.c
@@ -321,8 +321,8 @@ present_unflip(ScreenPtr screen)
 
     /* Update the screen pixmap with the current flip pixmap contents
      */
-    if (screen_priv->flip_pixmap) {
-        present_copy_region(&screen->GetScreenPixmap(screen)->drawable,
+    if (screen_priv->flip_pixmap && screen_priv->flip_window) {
+        present_copy_region(&screen_priv->flip_window->drawable,
                             screen_priv->flip_pixmap,
                             NULL, 0, 0);
     }
commit 8bdd2ccc776ded3f527596b5009ef25129aa3287
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Nov 11 18:03:42 2013 -0800

    present: Block for wait_fence in present_execute
    
    Pend presentation until wait_fence is also triggered by having the
    SyncFence trigger invoke present_execute once triggered.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/present/present.c b/present/present.c
index 67d7f6e..16dc381 100644
--- a/present/present.c
+++ b/present/present.c
@@ -453,6 +453,26 @@ present_check_flip_window (WindowPtr window)
 }
 
 /*
+ * Called when the wait fence is triggered; just gets the current msc/ust and
+ * calls present_execute again. That will re-check the fence and pend the
+ * request again if it's still not actually ready
+ */
+static void
+present_wait_fence_triggered(void *param)
+{
+    present_vblank_ptr  vblank = param;
+    WindowPtr           window = vblank->window;
+    uint64_t            ust = 0, crtc_msc = 0;
+
+    if (window) {
+        present_window_priv_ptr     window_priv = present_get_window_priv(window, TRUE);
+        if (window_priv)
+            (void) present_get_ust_msc(window, window_priv->crtc, &ust, &crtc_msc);
+    }
+    present_execute(vblank, ust, crtc_msc);
+}
+
+/*
  * Once the required MSC has been reached, execute the pending request.
  *
  * For requests to actually present something, either blt contents to
@@ -469,7 +489,10 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
     present_screen_priv_ptr     screen_priv = present_screen_priv(window->drawable.pScreen);
 
     if (vblank->wait_fence) {
-        /* XXX check fence, queue if not ready */
+        if (!present_fence_check_triggered(vblank->wait_fence)) {
+            present_fence_set_callback(vblank->wait_fence, present_wait_fence_triggered, vblank);
+            return;
+        }
     }
 
     xorg_list_del(&vblank->event_queue);
@@ -654,6 +677,12 @@ present_pixmap(WindowPtr window,
             target_msc--;
     }
 
+    if (wait_fence) {
+        vblank->wait_fence = present_fence_create(wait_fence);
+        if (!vblank->wait_fence)
+            goto no_mem;
+    }
+
     if (idle_fence) {
         vblank->idle_fence = present_fence_create(idle_fence);
         if (!vblank->idle_fence)
@@ -764,6 +793,9 @@ present_vblank_destroy(present_vblank_ptr vblank)
     if (vblank->update)
         RegionDestroy(vblank->update);
 
+    if (vblank->wait_fence)
+        present_fence_destroy(vblank->wait_fence);
+
     if (vblank->idle_fence)
         present_fence_destroy(vblank->idle_fence);
 
diff --git a/present/present_event.c b/present/present_event.c
index a30bc82..a8f7176 100644
--- a/present/present_event.c
+++ b/present/present_event.c
@@ -26,8 +26,6 @@
 
 #include "present_priv.h"
 
-#include "present_priv.h"
-
 RESTYPE present_event_type;
 
 static int
diff --git a/present/present_fence.c b/present/present_fence.c
index db5efca..e09657d 100644
--- a/present/present_fence.c
+++ b/present/present_fence.c
@@ -37,6 +37,8 @@
 struct present_fence {
     SyncTrigger         trigger;
     SyncFence           *fence;
+    void                (*callback)(void *param);
+    void                *param;
 };
 
 /*
@@ -45,12 +47,18 @@ struct present_fence {
 static Bool
 present_fence_sync_check_trigger(SyncTrigger *trigger, XSyncValue oldval)
 {
-    return FALSE;
+    struct present_fence        *present_fence = container_of(trigger, struct present_fence, trigger);
+
+    return present_fence->callback != NULL;
 }
 
 static void
 present_fence_sync_trigger_fired(SyncTrigger *trigger)
 {
+    struct present_fence        *present_fence = container_of(trigger, struct present_fence, trigger);
+
+    if (present_fence->callback)
+        (*present_fence->callback)(present_fence->param);
 }
 
 static void
@@ -101,6 +109,25 @@ present_fence_set_triggered(struct present_fence *present_fence)
             (*present_fence->fence->funcs.SetTriggered) (present_fence->fence);
 }
 
+Bool
+present_fence_check_triggered(struct present_fence *present_fence)
+{
+    if (!present_fence)
+        return TRUE;
+    if (!present_fence->fence)
+        return TRUE;
+    return (*present_fence->fence->funcs.CheckTriggered)(present_fence->fence);
+}
+
+void
+present_fence_set_callback(struct present_fence *present_fence,
+                           void (*callback) (void *param),
+                           void *param)
+{
+    present_fence->callback = callback;
+    present_fence->param = param;
+}
+
 XID
 present_fence_id(struct present_fence *present_fence)
 {
diff --git a/present/present_priv.h b/present/present_priv.h
index 40c88dd..500c7c2 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -249,6 +249,14 @@ present_fence_destroy(struct present_fence *present_fence);
 void
 present_fence_set_triggered(struct present_fence *present_fence);
 
+Bool
+present_fence_check_triggered(struct present_fence *present_fence);
+
+void
+present_fence_set_callback(struct present_fence *present_fence,
+                           void (*callback)(void *param),
+                           void *param);
+
 XID
 present_fence_id(struct present_fence *present_fence);
 
@@ -271,6 +279,13 @@ void
 present_destroy_notifies(present_notify_ptr notifies, int num_notifies);
 
 /*
+ * present_redirect.c
+ */
+
+WindowPtr
+present_redirect(ClientPtr client, WindowPtr target);
+
+/*
  * present_request.c
  */
 int
commit e5a188cb919edee2e3a03054276bce0db02f7b62
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Nov 9 12:36:47 2013 -0800

    present: Signal destroyed flip window with vblank->window == NULL
    
    This eliminates dereferencing freed window pointers when there is a
    flip for that window in progress. The flip will complete, and then
    immediately get undone (as we can't stop an in-progress flip).
    
    Remove the vblank->window_destroyed field as we can signal this with
    vblank->window == NULL instead.
    
    Change check to vblank->window == NULL in:
    
    	present_flip_notify
    
    Add check for vblank->window == NULL in:
    	present_vblank_notify
    	present_execute
    
    present_flip_notify was also using vblank->window->drawable.pScreen,
    so stop doing that and use vblank->screen instead.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/present/present.c b/present/present.c
index bfafa92..67d7f6e 100644
--- a/present/present.c
+++ b/present/present.c
@@ -171,7 +171,8 @@ present_vblank_notify(present_vblank_ptr vblank, CARD8 kind, CARD8 mode, uint64_
 {
     int         n;
 
-    present_send_complete_notify(vblank->window, kind, mode, vblank->serial, ust, crtc_msc - vblank->msc_offset);
+    if (vblank->window)
+        present_send_complete_notify(vblank->window, kind, mode, vblank->serial, ust, crtc_msc - vblank->msc_offset);
     for (n = 0; n < vblank->num_notifies; n++) {
         WindowPtr   window = vblank->notifies[n].window;
         CARD32      serial = vblank->notifies[n].serial;
@@ -336,8 +337,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc);
 static void
 present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
 {
-    WindowPtr                   window = vblank->window;
-    ScreenPtr                   screen = window->drawable.pScreen;
+    ScreenPtr                   screen = vblank->screen;
     present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
 
     DebugPresent(("\tn %p %8lld: %08lx -> %08lx\n", vblank, vblank->target_msc,
@@ -363,8 +363,7 @@ present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
     if (vblank->abort_flip)
         present_unflip(screen);
 
-    if (!vblank->window_destroyed)
-        present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, ust, crtc_msc);
+    present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, ust, crtc_msc);
     present_vblank_destroy(vblank);
 }
 
@@ -474,7 +473,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
     }
 
     xorg_list_del(&vblank->event_queue);
-    if (vblank->pixmap) {
+    if (vblank->pixmap && vblank->window) {
 
         if (vblank->flip && screen_priv->flip_pending == NULL && !screen_priv->unflip_event_id) {
 
diff --git a/present/present_priv.h b/present/present_priv.h
index a92b62a..40c88dd 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -72,8 +72,6 @@ struct present_vblank {
     Bool                flip;
     Bool                sync_flip;
     Bool                abort_flip;
-
-    Bool                window_destroyed;
 };
 
 typedef struct present_screen_priv {
diff --git a/present/present_screen.c b/present/present_screen.c
index 50b2b2d..2702cd6 100644
--- a/present/present_screen.c
+++ b/present/present_screen.c
@@ -92,7 +92,7 @@ present_clear_window_flip(WindowPtr window)
 
     if (flip_pending && flip_pending->window == window) {
         assert (flip_pending->abort_flip);
-        flip_pending->window_destroyed = TRUE;
+        flip_pending->window = NULL;
     }
     if (screen_priv->flip_window == window)
         screen_priv->flip_window = NULL;
commit a5bcc4f7b9499caf8993f0a6ef96088553399ca3
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Nov 9 12:33:02 2013 -0800

    present: Ignore event_id 0 from driver vblank notify
    
    We use event_id 0 to mean 'no such event'; if a driver sends us that
    event_id, make sure we don't accidentally match it.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/present/present.c b/present/present.c
index 228d43a..bfafa92 100644
--- a/present/present.c
+++ b/present/present.c
@@ -374,6 +374,8 @@ present_event_notify(uint64_t event_id, uint64_t ust, uint64_t msc)
     present_vblank_ptr  vblank, tmp;
     int                 s;
 
+    if (!event_id)
+        return;
     DebugPresent(("\te %lld ust %lld msc %lld\n", event_id, ust, msc));
     xorg_list_for_each_entry_safe(vblank, tmp, &present_exec_queue, event_queue) {
         if (vblank->event_id == event_id) {
@@ -398,6 +400,7 @@ present_event_notify(uint64_t event_id, uint64_t ust, uint64_t msc)
             DebugPresent(("\tun %lld\n", event_id));
             screen_priv->unflip_event_id = 0;
             present_flip_idle(screen);
+            return;
         }
     }
 }
commit 4f3c37a1f17ffcfbbff71d217e1caad3d0148c90
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Nov 7 14:17:12 2013 -0800

    present: Round fake MSC computations intead of truncating
    
    If the timer fired too early, we'd sometimes mis-compute the MSC for
    fake vblanks. Rounding the computation to the nearest MSC fixes this nicely.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/present/present_fake.c b/present/present_fake.c
index a677592..e550e98 100644
--- a/present/present_fake.c
+++ b/present/present_fake.c
@@ -42,7 +42,7 @@ present_fake_get_ust_msc(ScreenPtr screen, uint64_t *ust, uint64_t *msc)
     present_screen_priv_ptr screen_priv = present_screen_priv(screen);
 
     *ust = GetTimeInMicros();
-    *msc = *ust / screen_priv->fake_interval;
+    *msc = (*ust + screen_priv->fake_interval / 2) / screen_priv->fake_interval;
     return Success;
 }
 


More information about the xorg-commit mailing list