On Sun, 21 Feb 2010 05:26:00 +0100
Mario Kleiner mario.klei...@tuebingen.mpg.de wrote:
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.klei...@tuebingen.mpg.de
---
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 baf0df8..7f40d28 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -64,6 +64,8 @@ typedef struct _DRI2Drawable {
CARD64swap_count;
CARD64target_sbc; /* -1 means no SBC wait outstanding */
CARD64last_swap_target; /* most recently queued swap target
*/
+CARD64last_swap_msc; /* msc at completion of most recent
swap */
+CARD64last_swap_ust; /* ust at completion of most recent
swap */
int swap_limit; /* for N-buffering */
} DRI2DrawableRec, *DRI2DrawablePtr;
@@ -142,6 +144,8 @@ DRI2CreateDrawable(DrawablePtr pDraw)
pPriv-swap_interval = 1;
pPriv-last_swap_target = -1;
pPriv-swap_limit = 1; /* default to double buffering */
+pPriv-last_swap_msc = 0;
+pPriv-last_swap_ust = 0;
if (pDraw-type == DRAWABLE_WINDOW)
{
@@ -518,6 +522,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);
}
@@ -714,8 +721,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);
Nice fix, thanks. This should make OML work a bit more like the
spec says it should. :)
Reviewed-by: Jesse Barnes jbar...@virtuousgeek.org
--
Jesse Barnes, Intel Open Source Technology Center
___
xorg-devel mailing list
xorg-devel@lists.x.org
http://lists.x.org/mailman/listinfo/xorg-devel