summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-07-10 09:21:51 +0100
committerDave Airlie <airlied@redhat.com>2012-09-20 09:32:14 +1000
commite8b2000e5f6e19f1da23bfef8ed9e833c7643e54 (patch)
treee85a3809d691c79ffa84678aeac2cf62393c82af
parent70e5766874a919039678bb2ed75f2ccea0cb4345 (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.c54
-rw-r--r--hw/xfree86/dri2/dri2.h22
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(&region, &box, 0);
+
+ (*ds->CopyRegion)(pDraw, &region, 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(&region, &box, 0);
-
- pPriv->swapsPending++;
-
- dri2_copy_region(pDraw, &region, 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);