[PATCH 2/3] glx/dri3: Track separate (ust, msc) for PresentPixmap vs. PresentNotifyMsc

Mario Kleiner mario.kleiner.de at gmail.com
Mon Nov 24 19:00:03 PST 2014


Prevent calls to glXGetSyncValuesOML() and glXWaitForMscOML()
from overwriting the (ust,msc) values of the last successfull
swapbuffers call (PresentPixmapCompleteNotify event), as
glXWaitForSbcOML() relies on those values corresponding to
the most recent completed swap, not to whatever was last
returned from the server.

Problematic call sequence without this patch would have been, e.g.,

glXSwapBuffers()
... wait ...
swap completes -> PresentPixmapComplete event -> (ust,msc)
updated to reflect swap completion time and count.
... wait for at least 1 video refresh cycle/vblank increment.

glXGetSyncValuesOML()
-> PresentNotifyMsc event overwrites (ust,msc) of swap
completion with (ust,msc) of most recent vblank

glXWaitForSbcOML()
-> Returns sbc of last completed swap but (ust,msc) of last
completed vblank, not of last completed swap.
-> Client is confused.

Do this by tracking a separate set of (ust, msc) for the
dri3_wait_for_msc() call than for the dri3_wait_for_sbc()
call.

This makes the glXWaitForSbcOML() call robust again and restores
consistent behaviour with the DRI2 implementation.

Fixes applications originally written and tested against
DRI2 which also rely on this not regressing under DRI3/Present,
e.g., Neuro-Science software like Psychtoolbox-3.

This patch fixes the problem.

Cc: "10.3 10.4" <mesa-stable at lists.freedesktop.org>
Signed-off-by: Mario Kleiner <mario.kleiner.de at gmail.com>
---
 src/glx/dri3_glx.c  | 11 +++++++----
 src/glx/dri3_priv.h |  5 ++++-
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index b4ac278..5796491 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -420,11 +420,14 @@ dri3_handle_present_event(struct dri3_drawable *priv, xcb_present_generic_event_
 
          if (psc->show_fps_interval)
             show_fps(priv, ce->ust);
+
+         priv->ust = ce->ust;
+         priv->msc = ce->msc;
       } else {
          priv->recv_msc_serial = ce->serial;
+         priv->vblank_ust = ce->ust;
+         priv->vblank_msc = ce->msc;
       }
-      priv->ust = ce->ust;
-      priv->msc = ce->msc;
       break;
    }
    case XCB_PRESENT_EVENT_IDLE_NOTIFY: {
@@ -498,8 +501,8 @@ dri3_wait_for_msc(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
       }
    }
 
-   *ust = priv->ust;
-   *msc = priv->msc;
+   *ust = priv->vblank_ust;
+   *msc = priv->vblank_msc;
    *sbc = priv->recv_sbc;
 
    return 1;
diff --git a/src/glx/dri3_priv.h b/src/glx/dri3_priv.h
index 8e46640..222deb0 100644
--- a/src/glx/dri3_priv.h
+++ b/src/glx/dri3_priv.h
@@ -182,9 +182,12 @@ struct dri3_drawable {
    uint64_t send_sbc;
    uint64_t recv_sbc;
 
-   /* Last received UST/MSC values */
+   /* Last received UST/MSC values for pixmap present complete */
    uint64_t ust, msc;
 
+   /* Last received UST/MSC values for vblank */
+   uint64_t vblank_ust, vblank_msc;
+
    /* Serial numbers for tracking wait_for_msc events */
    uint32_t send_msc_serial;
    uint32_t recv_msc_serial;
-- 
1.9.1



More information about the xorg-devel mailing list