From: Pauli Nieminen <[email protected]> Client has to be allowed to call swap buffers before last_swap_target has been passed if driver implements triple buffering with swap_interval.
Time that swap may come before reaching last_swap_target is swap_limit * swap_interval if application renders very fast until throttled. Signed-off-by: Pauli Nieminen <[email protected]> --- hw/xfree86/dri2/dri2.c | 21 +++++++++++++++++++-- 1 files changed, 19 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index af3bcae..44a8348 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -791,6 +791,14 @@ DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable) return FALSE; } +#ifndef WORD64 +# ifdef LONG64 +typedef long INT64; +# else +typedef long long INT64; +#endif +#endif + int DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc, CARD64 divisor, CARD64 remainder, CARD64 *swap_target, @@ -854,12 +862,21 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc, * got enabled. */ if (ds->GetMSC) { + INT64 msc_diff; + INT64 future_frames_allowed = pPriv->swap_limit * pPriv->swap_interval; if (!(*ds->GetMSC)(pDraw, &ust, ¤t_msc)) pPriv->last_swap_target = 0; - if (current_msc < pPriv->last_swap_target) - pPriv->last_swap_target = current_msc; + msc_diff = (INT64)pPriv->last_swap_target - (INT64)current_msc; + /* + * If current_msc is more than swap_limit * swap_interval in future + * assume there was CRTC switch. That requires fixing swap_target for + * driver. + */ + if (msc_diff < future_frames_allowed) + pPriv->last_swap_target = current_msc + + pPriv->swapsPending * pPriv->swap_interval; } /* -- 1.7.4.1 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
