diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-07-10 09:21:51 +0100 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-09-20 09:32:14 +1000 |
commit | e8b2000e5f6e19f1da23bfef8ed9e833c7643e54 (patch) | |
tree | e85a3809d691c79ffa84678aeac2cf62393c82af | |
parent | 70e5766874a919039678bb2ed75f2ccea0cb4345 (diff) |
dri2: Pass AsyncSwap [swap_interval=0] requests to the drivers
Currently, the midlayer dri2 code intercepts swap_interval=0 (ala
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.
v2: Only invalidate the drawable on the behest of the backend, so that
existing behaviour of not invalidating for async blit copies is
preserved, suggested by Simon Farnsworh. And rebase for the intervening
12 months since v1.
v3: Time for another rebase.
v4: Rebase on top of Prime.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
Cc: Kristian Høgsberg <krh@bitplanet.net>
Cc: Ville Syrjälä <ville.syrjala@nokia.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Michel Dänzer <michel@daenzer.net>
Cc: Simon Farnsworth <simon.farnsworth@onelan.co.uk>
Reviewed-by: Simon Farnsworth <simon.farnsworth@onelan.co.uk>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | hw/xfree86/dri2/dri2.c | 54 | ||||
-rw-r--r-- | hw/xfree86/dri2/dri2.h | 22 |
2 files changed, 59 insertions, 17 deletions
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 40963c3b0..4e4ddd9c8 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -130,6 +130,8 @@ typedef struct _DRI2Screen { HandleExposuresProcPtr HandleExposures; + DRI2AsyncSwapProcPtr AsyncSwap; + ConfigNotifyProcPtr ConfigNotify; DRI2CreateBuffer2ProcPtr CreateBuffer2; DRI2DestroyBuffer2ProcPtr DestroyBuffer2; @@ -1090,6 +1092,29 @@ DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable) +static Bool +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); + + return FALSE; +} + int DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc, CARD64 divisor, CARD64 remainder, CARD64 * swap_target, @@ -1121,23 +1146,14 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc, return BadDrawable; } - /* Old DDX or no swap interval, just blit */ + /* Old DDX or no swap interval, just perform an immediate swap */ if (!ds->ScheduleSwap || !pPriv->swap_interval || pPriv->prime_id) { - BoxRec box; - RegionRec region; - - box.x1 = 0; - box.y1 = 0; - box.x2 = pDraw->width; - box.y2 = pDraw->height; - RegionInit(®ion, &box, 0); - - pPriv->swapsPending++; - - dri2_copy_region(pDraw, ®ion, pDestBuffer, pSrcBuffer); - DRI2SwapComplete(client, pDraw, target_msc, 0, 0, DRI2_BLIT_COMPLETE, - func, data); - return Success; + pPriv->swapsPending++; + if ((*ds->AsyncSwap)(client, pDraw, + pDestBuffer, pSrcBuffer, + func, data)) + DRI2InvalidateDrawable(pDraw); + return Success; } /* @@ -1504,6 +1520,12 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) ds->CopyRegion2 = info->CopyRegion2; } + if (info->version >= 10) { + ds->AsyncSwap = info->AsyncSwap; + } + if (ds->AsyncSwap == NULL) + ds->AsyncSwap = DRI2AsyncSwapBuffers; + /* * if the driver doesn't provide an AuthMagic function or the info struct * version is too low, call through LegacyAuthMagic diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index 1e7afddbd..64538eafe 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -101,6 +101,12 @@ typedef int (*DRI2ScheduleSwapProcPtr) (ClientPtr client, CARD64 divisor, CARD64 remainder, DRI2SwapEventPtr func, void *data); +typedef Bool (*DRI2AsyncSwapProcPtr)(ClientPtr client, + DrawablePtr pDraw, + DRI2BufferPtr pDestBuffer, + DRI2BufferPtr pSrcBuffer, + DRI2SwapEventPtr func, + void *data); typedef DRI2BufferPtr(*DRI2CreateBufferProcPtr) (DrawablePtr pDraw, unsigned int attachment, unsigned int format); @@ -205,7 +211,7 @@ typedef int (*DRI2GetParamProcPtr) (ClientPtr client, /** * Version of the DRI2InfoRec structure defined in this header */ -#define DRI2INFOREC_VERSION 9 +#define DRI2INFOREC_VERSION 10 typedef struct { unsigned int version; /**< Version of this struct */ @@ -252,6 +258,20 @@ typedef struct { DRI2CreateBuffer2ProcPtr CreateBuffer2; DRI2DestroyBuffer2ProcPtr DestroyBuffer2; DRI2CopyRegion2ProcPtr CopyRegion2; + + /* added in version 10 */ + + /* Used when the client requests swap_interval=0, i.e. swap immediately + * with no throttling. Whether to tear or not is left up to the driver. + * + * A return value of TRUE indicates that a buffer exchange occurred and + * that the DRI2 drawable requires invalidation (i.e. for the updated + * attachment names to be propagated back to the client.) A return value + * of FALSE implies that the back buffer was just copied onto the front, + * and that no invalidation is required as the buffer attachments remain + * the same. + */ + DRI2AsyncSwapProcPtr AsyncSwap; } DRI2InfoRec, *DRI2InfoPtr; extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info); |