Currently, the midlayer dri2 code intercepts vblank_mode=0 SwapBuffers and converts it to a CopyRegion request. This prevents the backend from doing anything meaningful in this case and typically ends up being vsync'ed since the drivers cannot distinguish it from a regular CopyRegion request.
Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> Cc: Jesse Barnes <jbar...@virtuousgeek.org> Cc: Kristian Høgsberg <k...@bitplanet.net> --- Sigh... I broke the patch with a last minute name change. Please pretend you never saw the previous patch. Thanks, -Chris --- hw/xfree86/dri2/dri2.c | 47 ++++++++++++++++++++++++++++++++--------------- hw/xfree86/dri2/dri2.h | 12 +++++++++++- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index bf7ebb9..03ae1cc 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -98,6 +98,7 @@ typedef struct _DRI2Screen { DRI2CreateBufferProcPtr CreateBuffer; DRI2DestroyBufferProcPtr DestroyBuffer; DRI2CopyRegionProcPtr CopyRegion; + DRI2AsyncSwapProcPtr AsyncSwap; DRI2ScheduleSwapProcPtr ScheduleSwap; DRI2GetMSCProcPtr GetMSC; DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC; @@ -791,6 +792,27 @@ DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable) return FALSE; } +static void +DRI2AsyncSwapBuffers(ClientPtr client, + DrawablePtr pDraw, + DRI2BufferPtr pDestBuffer, + DRI2BufferPtr pSrcBuffer, + DRI2SwapEventPtr func, void *data) +{ + DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); + BoxRec box; + RegionRec region; + + box.x1 = 0; + box.y1 = 0; + box.x2 = pDraw->width; + box.y2 = pDraw->height; + RegionInit(®ion, &box, 0); + + (*ds->CopyRegion)(pDraw, ®ion, pDestBuffer, pSrcBuffer); + DRI2SwapComplete(client, pDraw, 0, 0, 0, DRI2_BLIT_COMPLETE, func, data); +} + int DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc, CARD64 divisor, CARD64 remainder, CARD64 *swap_target, @@ -824,21 +846,11 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc, /* Old DDX or no swap interval, just blit */ if (!ds->ScheduleSwap || !pPriv->swap_interval) { - BoxRec box; - RegionRec region; - - box.x1 = 0; - box.y1 = 0; - box.x2 = pDraw->width; - box.y2 = pDraw->height; - RegionInit(®ion, &box, 0); - - pPriv->swapsPending++; - - (*ds->CopyRegion)(pDraw, ®ion, pDestBuffer, pSrcBuffer); - DRI2SwapComplete(client, pDraw, target_msc, 0, 0, DRI2_BLIT_COMPLETE, - func, data); - return Success; + pPriv->swapsPending++; + (*ds->AsyncSwap)(client, pDraw, + pDestBuffer, pSrcBuffer, + func, data); + return Success; } /* @@ -1128,6 +1140,11 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) ds->AuthMagic = info->AuthMagic; } + ds->AsyncSwap = DRI2AsyncSwapBuffers; + if (info->version >= 6) { + ds->AsyncSwap = info->AsyncSwap; + } + /* * if the driver doesn't provide an AuthMagic function or the info struct * version is too low, it relies on the old method (using libdrm) or fail diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index fe0bf6c..15f9167 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -104,6 +104,12 @@ typedef int (*DRI2ScheduleSwapProcPtr)(ClientPtr client, CARD64 remainder, DRI2SwapEventPtr func, void *data); +typedef void (*DRI2AsyncSwapProcPtr)(ClientPtr client, + DrawablePtr pDraw, + DRI2BufferPtr pDestBuffer, + DRI2BufferPtr pSrcBuffer, + DRI2SwapEventPtr func, + void *data); typedef DRI2BufferPtr (*DRI2CreateBufferProcPtr)(DrawablePtr pDraw, unsigned int attachment, unsigned int format); @@ -161,7 +167,7 @@ typedef void (*DRI2InvalidateProcPtr)(DrawablePtr pDraw, /** * Version of the DRI2InfoRec structure defined in this header */ -#define DRI2INFOREC_VERSION 5 +#define DRI2INFOREC_VERSION 6 typedef struct { unsigned int version; /**< Version of this struct */ @@ -189,6 +195,10 @@ typedef struct { /* added in version 5 */ DRI2AuthMagicProcPtr AuthMagic; + + /* added in version 6 */ + + DRI2AsyncSwapProcPtr AsyncSwap; } DRI2InfoRec, *DRI2InfoPtr; extern _X_EXPORT int DRI2EventBase; -- 1.7.5.1 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel