summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-03-05 20:30:20 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2011-08-25 11:57:19 +0100
commit9e92c256853fa29bddd27e41fdd24e0b140e7fd4 (patch)
treebfa74a75fa2d2ca9453c1c24966a5d3a87ffe885
parent5d791002974963c334993fc53ed6a5168a590ffb (diff)
dri2: Pass AsyncSwap [vblank_mode=0] requests to the drivers
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@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>
-rw-r--r--hw/xfree86/dri2/dri2.c48
-rw-r--r--hw/xfree86/dri2/dri2.h15
2 files changed, 47 insertions, 16 deletions
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index af3bcaefe..298ae5a6f 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 2a41ead5b..ca827210a 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;