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 {
>      CARD64            swap_count;
>      CARD64            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;
>  
> @@ -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

Reply via email to