[PATCH 2/4] dri2: Pass AsyncSwap [vblank_mode=0] requests to the drivers
Chris Wilson
chris at chris-wilson.co.uk
Sun Jun 12 02:47:35 PDT 2011
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 <chris at chris-wilson.co.uk>
Cc: Jesse Barnes <jbarnes at virtuousgeek.org>
Cc: Kristian Høgsberg <krh at bitplanet.net>
Cc: Ville Syrjälä <ville.syrjala at nokia.com>
Cc: Dave Airlie <airlied at redhat.com>
Cc: Michel Dänzer <michel at daenzer.net>
---
hw/xfree86/dri2/dri2.c | 48 +++++++++++++++++++++++++++++++++---------------
hw/xfree86/dri2/dri2.h | 15 ++++++++++++++-
2 files changed, 47 insertions(+), 16 deletions(-)
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index bf7ebb9..d837852 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,12 @@ 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);
+ DRI2InvalidateDrawable(pDraw);
+ return Success;
}
/*
@@ -1128,6 +1141,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..d68383c 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,13 @@ typedef struct {
/* added in version 5 */
DRI2AuthMagicProcPtr AuthMagic;
+
+ /* added in version 6 */
+
+ /* Used when the client requests vblank_mode=0, i.e. swap immediately
+ * with no throttling. Whether to tear or not is left up to the driver.
+ */
+ DRI2AsyncSwapProcPtr AsyncSwap;
} DRI2InfoRec, *DRI2InfoPtr;
extern _X_EXPORT int DRI2EventBase;
--
1.7.5.1
More information about the xorg-devel
mailing list