[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(&region, &box, 0);
+
+	(*ds->CopyRegion)(pDraw, &region, 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(&region, &box, 0);
-
-	pPriv->swapsPending++;
-
-	(*ds->CopyRegion)(pDraw, &region, 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