diff options
author | Mario Kleiner <mario.kleiner@tuebingen.mpg.de> | 2010-02-21 05:26:00 +0100 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2010-05-21 13:55:17 +1000 |
commit | a56178402ede82ed3ffd81439b2efc4a39f2779e (patch) | |
tree | f9c56c005d8a2eb31176f57cc32a4eba704ca616 /hw | |
parent | a9b70da1afe7361955a19d34bb5e9b94dc156889 (diff) |
DRI2WaitSbc(): Fixes for correct semantic of glXWaitForSbcOML()
Added implementation for case target_sbc == 0. In that case, the
function shall schedule a wait until all pending swaps for the drawable
have completed.
Fix for non-blocking case. Old implementation returned random,
uninitialized values for (ust,msc,sbc) if it returned immediately
without scheduling a wait due to sbc >= target_sbc.
Now if function doesn't schedule a wait, but returns immediately,
it returns the (ust,msc,sbc) of the most recently completed swap,
i.e., the UST and MSC corresponding to the time when the returned
current SBC was reached.
Signed-off-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
(cherry picked from commit 751e8c09d34df4b41e8d8384a3ec1bf5cb8ca028)
Diffstat (limited to 'hw')
-rw-r--r-- | hw/xfree86/dri2/dri2.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index cb227be3f..ef838ff6b 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -64,6 +64,8 @@ typedef struct _DRI2Drawable { CARD64 swap_count; int64_t target_sbc; /* -1 means no SBC wait outstanding */ CARD64 last_swap_target; /* most recently queued swap target */ + CARD64 last_swap_msc; /* msc at completion of most recent swap */ + CARD64 last_swap_ust; /* ust at completion of most recent swap */ int swap_limit; /* for N-buffering */ } DRI2DrawableRec, *DRI2DrawablePtr; @@ -148,6 +150,8 @@ DRI2CreateDrawable(DrawablePtr pDraw) pPriv->last_swap_target = 0; pPriv->swap_limit = 1; /* default to double buffering */ + pPriv->last_swap_msc = 0; + pPriv->last_swap_ust = 0; if (pDraw->type == DRAWABLE_WINDOW) { @@ -553,6 +557,9 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame, if (swap_complete) swap_complete(client, swap_data, type, ust, frame, pPriv->swap_count); + pPriv->last_swap_msc = frame; + pPriv->last_swap_ust = ust; + DRI2WakeClient(client, pDraw, frame, tv_sec, tv_usec); } @@ -727,8 +734,22 @@ DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc, if (pPriv == NULL) return BadDrawable; - if (pPriv->swap_count >= target_sbc) - return Success; + /* target_sbc == 0 means to block until all pending swaps are + * finished. Recalculate target_sbc to get that behaviour. + */ + if (target_sbc == 0) + target_sbc = pPriv->swap_count + pPriv->swapsPending; + + /* If current swap count already >= target_sbc, + * return immediately with (ust, msc, sbc) triplet of + * most recent completed swap. + */ + if (pPriv->swap_count >= target_sbc) { + *sbc = pPriv->swap_count; + *msc = pPriv->last_swap_msc; + *ust = pPriv->last_swap_ust; + return Success; + } pPriv->target_sbc = target_sbc; DRI2BlockClient(client, pDraw); |