cdde67c
From 20edb1d61db80f5fedb4d3eea60c67d438502238 Mon Sep 17 00:00:00 2001
Kristian Høgsberg 3457ada
From: =?utf-8?q?Kristian=20H=C3=B8gsberg?= <krh@redhat.com>
Kristian Høgsberg 3457ada
Date: Wed, 29 Jul 2009 08:26:14 -0400
Kristian Høgsberg 3457ada
Subject: [PATCH] DRI2 Page Flipping
Kristian Høgsberg 3457ada
Kristian Høgsberg 3457ada
---
Kristian Høgsberg 3457ada
 glx/glxcontext.h          |    4 ++
Kristian Høgsberg 3457ada
 glx/glxdri2.c             |   47 ++++++++++++++----
Kristian Høgsberg 3457ada
 glx/glxext.c              |    3 +
Kristian Høgsberg 3457ada
 glx/glxserver.h           |   18 +++----
Kristian Høgsberg 3457ada
 hw/xfree86/dri2/dri2.c    |  118 +++++++++++++++++++++++++++++++++++++++++++-
Kristian Høgsberg 3457ada
 hw/xfree86/dri2/dri2.h    |   12 ++++-
Kristian Høgsberg 3457ada
 hw/xfree86/dri2/dri2ext.c |   25 +++++++++-
Kristian Høgsberg 3457ada
 7 files changed, 200 insertions(+), 27 deletions(-)
Kristian Høgsberg 3457ada
Kristian Høgsberg 3457ada
diff --git a/glx/glxcontext.h b/glx/glxcontext.h
Kristian Høgsberg 3457ada
index 70a1411..79bc083 100644
Kristian Høgsberg 3457ada
--- a/glx/glxcontext.h
Kristian Høgsberg 3457ada
+++ b/glx/glxcontext.h
Kristian Høgsberg 3457ada
@@ -55,6 +55,10 @@ struct __GLXcontext {
Kristian Høgsberg 3457ada
 				     unsigned long mask);
Kristian Høgsberg 3457ada
     int            (*forceCurrent)  (__GLXcontext *context);
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
+    Bool           (*wait)          (__GLXcontext *context,
Kristian Høgsberg 3457ada
+				     __GLXclientState *cl,
Kristian Høgsberg 3457ada
+				     int *error);
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
     __GLXtextureFromPixmap *textureFromPixmap;
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
     /*
Kristian Høgsberg 3457ada
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
Kristian Høgsberg 3457ada
index ed7fb4c..4b89c31 100644
Kristian Høgsberg 3457ada
--- a/glx/glxdri2.c
Kristian Høgsberg 3457ada
+++ b/glx/glxdri2.c
Kristian Høgsberg 3457ada
@@ -70,6 +70,7 @@ struct __GLXDRIscreen {
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
     const __DRIcoreExtension *core;
Kristian Høgsberg 3457ada
     const __DRIdri2Extension *dri2;
Kristian Høgsberg 3457ada
+    const __DRI2flushExtension *flush;
Kristian Høgsberg 3457ada
     const __DRIcopySubBufferExtension *copySubBuffer;
Kristian Høgsberg 3457ada
     const __DRIswapControlExtension *swapControl;
Kristian Høgsberg 3457ada
     const __DRItexBufferExtension *texBuffer;
Kristian Høgsberg 3457ada
@@ -132,17 +133,6 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *drawable,
Kristian Høgsberg 3457ada
 		   DRI2BufferFrontLeft, DRI2BufferBackLeft);
Kristian Høgsberg 3457ada
 }
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
-static GLboolean
Kristian Høgsberg 3457ada
-__glXDRIdrawableSwapBuffers(__GLXdrawable *drawable)
Kristian Høgsberg 3457ada
-{
Kristian Høgsberg 3457ada
-    __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
Kristian Høgsberg 3457ada
-
Kristian Høgsberg 3457ada
-    __glXDRIdrawableCopySubBuffer(drawable, 0, 0,
Kristian Høgsberg 3457ada
-				  private->width, private->height);
Kristian Høgsberg 3457ada
-
Kristian Høgsberg 3457ada
-    return TRUE;
Kristian Høgsberg 3457ada
-}
Kristian Høgsberg 3457ada
-
Kristian Høgsberg 3457ada
 static void
Kristian Høgsberg 3457ada
 __glXDRIdrawableWaitX(__GLXdrawable *drawable)
Kristian Høgsberg 3457ada
 {
Kristian Høgsberg 3457ada
@@ -177,6 +167,20 @@ __glXDRIdrawableWaitGL(__GLXdrawable *drawable)
Kristian Høgsberg 3457ada
 		   DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
Kristian Høgsberg 3457ada
 }
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
+static GLboolean
Kristian Høgsberg 3457ada
+__glXDRIdrawableSwapBuffers(__GLXdrawable *drawable)
Kristian Høgsberg 3457ada
+{
Kristian Høgsberg 3457ada
+    __GLXDRIdrawable *priv = (__GLXDRIdrawable *) drawable;
Kristian Høgsberg 3457ada
+    __GLXDRIscreen *screen = priv->screen;
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    (*screen->flush->flushInvalidate)(priv->driDrawable);
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    if (DRI2SwapBuffers(drawable->pDraw) != Success)
Kristian Høgsberg 3457ada
+	return FALSE;
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    return TRUE;
Kristian Høgsberg 3457ada
+}
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
 static int
Kristian Høgsberg 3457ada
 __glXDRIdrawableSwapInterval(__GLXdrawable *drawable, int interval)
Kristian Høgsberg 3457ada
 {
Kristian Høgsberg 3457ada
@@ -241,6 +245,18 @@ __glXDRIcontextForceCurrent(__GLXcontext *baseContext)
Kristian Høgsberg 3457ada
 					read->driDrawable);
Kristian Høgsberg 3457ada
 }
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
+static Bool
Kristian Høgsberg 3457ada
+__glXDRIcontextWait(__GLXcontext *baseContext,
Kristian Høgsberg 3457ada
+		    __GLXclientState *cl, int *error)
Kristian Høgsberg 3457ada
+{
Kristian Høgsberg 3457ada
+    if (DRI2WaitSwap(cl->client, baseContext->drawPriv->pDraw)) {
Kristian Høgsberg 3457ada
+	*error = cl->client->noClientException;
Kristian Høgsberg 3457ada
+	return TRUE;
Kristian Høgsberg 3457ada
+    }
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    return FALSE;
Kristian Høgsberg 3457ada
+}
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
 #ifdef __DRI_TEX_BUFFER
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
 static int
Kristian Høgsberg 3457ada
@@ -346,6 +362,7 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
Kristian Høgsberg 3457ada
     context->base.copy              = __glXDRIcontextCopy;
Kristian Høgsberg 3457ada
     context->base.forceCurrent      = __glXDRIcontextForceCurrent;
Kristian Høgsberg 3457ada
     context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
Kristian Høgsberg 3457ada
+    context->base.wait              = __glXDRIcontextWait;
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
     context->driContext =
Kristian Høgsberg 3457ada
 	(*screen->dri2->createNewContext)(screen->driScreen,
Kristian Høgsberg 3457ada
@@ -581,6 +598,14 @@ initializeExtensions(__GLXDRIscreen *screen)
Kristian Høgsberg 3457ada
 	    LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n");
Kristian Høgsberg 3457ada
 	}
Kristian Høgsberg 3457ada
 #endif
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+#ifdef __DRI2_FLUSH
Kristian Høgsberg 3457ada
+	if (strcmp(extensions[i]->name, __DRI2_FLUSH) == 0 &&
Kristian Høgsberg 3457ada
+	    extensions[i]->version >= __DRI2_FLUSH_VERSION) {
Kristian Høgsberg 3457ada
+		screen->flush = (__DRI2flushExtension *) extensions[i];
Kristian Høgsberg 3457ada
+	}
Kristian Høgsberg 3457ada
+#endif
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
 	/* Ignore unknown extensions */
Kristian Høgsberg 3457ada
     }
Kristian Høgsberg 3457ada
 }
Kristian Høgsberg 3457ada
diff --git a/glx/glxext.c b/glx/glxext.c
Kristian Høgsberg 3457ada
index 19d70d4..f57ccf5 100644
Kristian Høgsberg 3457ada
--- a/glx/glxext.c
Kristian Høgsberg 3457ada
+++ b/glx/glxext.c
Kristian Høgsberg 3457ada
@@ -439,6 +439,9 @@ __GLXcontext *__glXForceCurrent(__GLXclientState *cl, GLXContextTag tag,
Kristian Høgsberg 3457ada
     	}
Kristian Høgsberg 3457ada
     }
Kristian Høgsberg 3457ada
     
Kristian Høgsberg 3457ada
+    if (cx->wait && (*cx->wait)(cx, cl, error))
Kristian Høgsberg 3457ada
+	return NULL;
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
     if (cx == __glXLastContext) {
Kristian Høgsberg 3457ada
 	/* No need to re-bind */
Kristian Høgsberg 3457ada
 	return cx;
Kristian Høgsberg 3457ada
diff --git a/glx/glxserver.h b/glx/glxserver.h
Kristian Høgsberg 3457ada
index 46c9382..3e62782 100644
Kristian Høgsberg 3457ada
--- a/glx/glxserver.h
Kristian Høgsberg 3457ada
+++ b/glx/glxserver.h
Kristian Høgsberg 3457ada
@@ -56,7 +56,14 @@
Kristian Høgsberg 3457ada
 #include <GL/gl.h>
Kristian Høgsberg 3457ada
 #include <GL/glxproto.h>
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
-/* For glxscreens.h */
Kristian Høgsberg 3457ada
+/*
Kristian Høgsberg 3457ada
+** GLX resources.
Kristian Høgsberg 3457ada
+*/
Kristian Høgsberg 3457ada
+typedef XID GLXContextID;
Kristian Høgsberg 3457ada
+typedef XID GLXPixmap;
Kristian Høgsberg 3457ada
+typedef XID GLXDrawable;
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+typedef struct __GLXclientStateRec __GLXclientState;
Kristian Høgsberg 3457ada
 typedef struct __GLXdrawable __GLXdrawable;
Kristian Høgsberg 3457ada
 typedef struct __GLXcontext __GLXcontext;
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
@@ -75,15 +82,6 @@ typedef struct __GLXcontext __GLXcontext;
Kristian Høgsberg 3457ada
 #define False 0
Kristian Høgsberg 3457ada
 #endif
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
-/*
Kristian Høgsberg 3457ada
-** GLX resources.
Kristian Høgsberg 3457ada
-*/
Kristian Høgsberg 3457ada
-typedef XID GLXContextID;
Kristian Høgsberg 3457ada
-typedef XID GLXPixmap;
Kristian Høgsberg 3457ada
-typedef XID GLXDrawable;
Kristian Høgsberg 3457ada
-
Kristian Høgsberg 3457ada
-typedef struct __GLXclientStateRec __GLXclientState;
Kristian Høgsberg 3457ada
-
Kristian Høgsberg 3457ada
 extern __GLXscreen *glxGetScreen(ScreenPtr pScreen);
Kristian Høgsberg 3457ada
 extern __GLXclientState *glxGetClient(ClientPtr pClient);
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
cdde67c
index d15ced1..7b9fb23 100644
Kristian Høgsberg 3457ada
--- a/hw/xfree86/dri2/dri2.c
Kristian Høgsberg 3457ada
+++ b/hw/xfree86/dri2/dri2.c
Kristian Høgsberg 3457ada
@@ -38,6 +38,7 @@
Kristian Høgsberg 3457ada
 #include "xf86Module.h"
Kristian Høgsberg 3457ada
 #include "scrnintstr.h"
Kristian Høgsberg 3457ada
 #include "windowstr.h"
Kristian Høgsberg 3457ada
+#include "dixstruct.h"
Kristian Høgsberg 3457ada
 #include "dri2.h"
cdde67c
 #include "xf86VGAarbiter.h"
Kristian Høgsberg 3457ada
 
cdde67c
@@ -56,7 +57,8 @@ typedef struct _DRI2Drawable {
Kristian Høgsberg 3457ada
     int			 height;
Kristian Høgsberg 3457ada
     DRI2BufferPtr	*buffers;
Kristian Høgsberg 3457ada
     int			 bufferCount;
Kristian Høgsberg 3457ada
-    unsigned int	 pendingSequence;
Kristian Høgsberg 3457ada
+    unsigned int	 swapPending;
Kristian Høgsberg 3457ada
+    ClientPtr		 blockedClient;
Kristian Høgsberg 3457ada
 } DRI2DrawableRec, *DRI2DrawablePtr;
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
 typedef struct _DRI2Screen {
cdde67c
@@ -68,6 +70,7 @@ typedef struct _DRI2Screen {
Kristian Høgsberg 3457ada
     DRI2CreateBufferProcPtr	 CreateBuffer;
Kristian Høgsberg 3457ada
     DRI2DestroyBufferProcPtr	 DestroyBuffer;
Kristian Høgsberg 3457ada
     DRI2CopyRegionProcPtr	 CopyRegion;
Kristian Høgsberg 3457ada
+    DRI2SwapBuffersProcPtr	 SwapBuffers;
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
     HandleExposuresProcPtr       HandleExposures;
Kristian Høgsberg 3457ada
 } DRI2ScreenRec, *DRI2ScreenPtr;
cdde67c
@@ -119,6 +122,8 @@ DRI2CreateDrawable(DrawablePtr pDraw)
Kristian Høgsberg 3457ada
     pPriv->height = pDraw->height;
Kristian Høgsberg 3457ada
     pPriv->buffers = NULL;
Kristian Høgsberg 3457ada
     pPriv->bufferCount = 0;
Kristian Høgsberg 3457ada
+    pPriv->swapPending = FALSE;
Kristian Høgsberg 3457ada
+    pPriv->blockedClient = NULL;
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
     if (pDraw->type == DRAWABLE_WINDOW)
Kristian Høgsberg 3457ada
     {
cdde67c
@@ -338,6 +343,106 @@ DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
Kristian Høgsberg 3457ada
     return Success;
Kristian Høgsberg 3457ada
 }
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
+static Bool
Kristian Høgsberg 3457ada
+DRI2FlipCheck(DrawablePtr pDraw)
Kristian Høgsberg 3457ada
+{
Kristian Høgsberg 3457ada
+    ScreenPtr pScreen = pDraw->pScreen;
Kristian Høgsberg 3457ada
+    WindowPtr pWin, pRoot;
Kristian Høgsberg 3457ada
+    PixmapPtr pWinPixmap, pRootPixmap;
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    if (pDraw->type == DRAWABLE_PIXMAP)
Kristian Høgsberg 3457ada
+	return TRUE;
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    pRoot = WindowTable[pScreen->myNum];
Kristian Høgsberg 3457ada
+    pRootPixmap = pScreen->GetWindowPixmap(pRoot);
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    pWin = (WindowPtr) pDraw;
Kristian Høgsberg 3457ada
+    pWinPixmap = pScreen->GetWindowPixmap(pWin);
Kristian Høgsberg 3457ada
+    if (pRootPixmap != pWinPixmap)
Kristian Høgsberg 3457ada
+	return FALSE;
Kristian Høgsberg 3457ada
+    if (!REGION_EQUAL(pScreen, &pWin->clipList, &pRoot->winSize))
Kristian Høgsberg 3457ada
+	return FALSE;
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    return TRUE;
Kristian Høgsberg 3457ada
+}
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+int
Kristian Høgsberg 3457ada
+DRI2SwapBuffers(DrawablePtr pDraw)
Kristian Høgsberg 3457ada
+{
Kristian Høgsberg 3457ada
+    DRI2ScreenPtr   ds = DRI2GetScreen(pDraw->pScreen);
Kristian Høgsberg 3457ada
+    DRI2DrawablePtr pPriv;
Kristian Høgsberg 3457ada
+    DRI2BufferPtr   pDestBuffer, pSrcBuffer;
Kristian Høgsberg 3457ada
+    int		    i;
Kristian Høgsberg 3457ada
+    BoxRec	    box;
Kristian Høgsberg 3457ada
+    RegionRec	    region;
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    pPriv = DRI2GetDrawable(pDraw);
Kristian Høgsberg 3457ada
+    if (pPriv == NULL)
Kristian Høgsberg 3457ada
+	return BadDrawable;
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    pDestBuffer = NULL;
Kristian Høgsberg 3457ada
+    pSrcBuffer = NULL;
Kristian Høgsberg 3457ada
+    for (i = 0; i < pPriv->bufferCount; i++)
Kristian Høgsberg 3457ada
+    {
Kristian Høgsberg 3457ada
+	if (pPriv->buffers[i]->attachment == DRI2BufferFrontLeft)
Kristian Høgsberg 3457ada
+	    pDestBuffer = pPriv->buffers[i];
Kristian Høgsberg 3457ada
+	if (pPriv->buffers[i]->attachment == DRI2BufferBackLeft)
Kristian Høgsberg 3457ada
+	    pSrcBuffer = pPriv->buffers[i];
Kristian Høgsberg 3457ada
+    }
Kristian Høgsberg 3457ada
+    if (pSrcBuffer == NULL || pDestBuffer == NULL)
Kristian Høgsberg 3457ada
+	return BadValue;
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    if (DRI2FlipCheck(pDraw) &&
Kristian Høgsberg 3457ada
+	(*ds->SwapBuffers)(pDraw, pDestBuffer, pSrcBuffer, pPriv))
Kristian Høgsberg 3457ada
+    {
Kristian Høgsberg 3457ada
+	pPriv->swapPending = TRUE;
Kristian Høgsberg 3457ada
+	return Success;
Kristian Høgsberg 3457ada
+    }
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    box.x1 = 0;
Kristian Høgsberg 3457ada
+    box.y1 = 0;
Kristian Høgsberg 3457ada
+    box.x2 = pDraw->width;
Kristian Høgsberg 3457ada
+    box.y2 = pDraw->height;
Kristian Høgsberg 3457ada
+    REGION_INIT(drawable->pDraw->pScreen, &region, &box, 0);
Kristian Høgsberg 3457ada
+    
Kristian Høgsberg 3457ada
+    return DRI2CopyRegion(pDraw, &region,
Kristian Høgsberg 3457ada
+			  DRI2BufferFrontLeft, DRI2BufferBackLeft);
Kristian Høgsberg 3457ada
+}
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+Bool
Kristian Høgsberg 3457ada
+DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable)
Kristian Høgsberg 3457ada
+{
Kristian Høgsberg 3457ada
+    DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable);
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    /* If we're currently waiting for a swap on this drawable, reset
Kristian Høgsberg 3457ada
+     * the request and suspend the client.  We only support one
Kristian Høgsberg 3457ada
+     * blocked client per drawable. */
Kristian Høgsberg 3457ada
+    if (pPriv->swapPending && pPriv->blockedClient == NULL) {
Kristian Høgsberg 3457ada
+	ResetCurrentRequest(client);
Kristian Høgsberg 3457ada
+	client->sequence--;
Kristian Høgsberg 3457ada
+	IgnoreClient(client);
Kristian Høgsberg 3457ada
+	pPriv->blockedClient = client;
Kristian Høgsberg 3457ada
+	return TRUE;
Kristian Høgsberg 3457ada
+    }
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    return FALSE;
Kristian Høgsberg 3457ada
+}
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+void
Kristian Høgsberg 3457ada
+DRI2SwapComplete(void *data)
Kristian Høgsberg 3457ada
+{
Kristian Høgsberg 3457ada
+    DRI2DrawablePtr pPriv = data;
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    if (pPriv->blockedClient)
Kristian Høgsberg 3457ada
+	AttendClient(pPriv->blockedClient);
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    pPriv->swapPending = FALSE;
Kristian Høgsberg 3457ada
+    pPriv->blockedClient = NULL;
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    if (pPriv->refCount == 0)
Kristian Høgsberg 3457ada
+	xfree(pPriv);
Kristian Høgsberg 3457ada
+}
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
 void
Kristian Høgsberg 3457ada
 DRI2DestroyDrawable(DrawablePtr pDraw)
Kristian Høgsberg 3457ada
 {
cdde67c
@@ -363,7 +468,11 @@ DRI2DestroyDrawable(DrawablePtr pDraw)
Kristian Høgsberg 3457ada
 	xfree(pPriv->buffers);
Kristian Høgsberg 3457ada
     }
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
-    xfree(pPriv);
Kristian Høgsberg 3457ada
+    /* If the window is destroyed while we have a swap pending, don't
Kristian Høgsberg 3457ada
+     * actually free the priv yet.  We'll need it in the DRI2SwapComplete()
Kristian Høgsberg 3457ada
+     * callback and we'll free it there once we're done. */
Kristian Høgsberg 3457ada
+    if (!pPriv->swapPending)
Kristian Høgsberg 3457ada
+	xfree(pPriv);
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
     if (pDraw->type == DRAWABLE_WINDOW)
Kristian Høgsberg 3457ada
     {
cdde67c
@@ -421,7 +530,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
cdde67c
         return FALSE;
cdde67c
     }
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
-    ds = xalloc(sizeof *ds);
Kristian Høgsberg 3457ada
+    ds = xcalloc(1, sizeof *ds);
Kristian Høgsberg 3457ada
     if (!ds)
Kristian Høgsberg 3457ada
 	return FALSE;
Kristian Høgsberg 3457ada
 
cdde67c
@@ -433,6 +542,9 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
Kristian Høgsberg 3457ada
     ds->DestroyBuffer  = info->DestroyBuffer;
Kristian Høgsberg 3457ada
     ds->CopyRegion     = info->CopyRegion;
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
+    if (info->version >= 4)
Kristian Høgsberg 3457ada
+	ds->SwapBuffers = info->SwapBuffers;
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
     dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
     xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] Setup complete\n");
Kristian Høgsberg 3457ada
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
Kristian Høgsberg 3457ada
index 175471a..42bdb09 100644
Kristian Høgsberg 3457ada
--- a/hw/xfree86/dri2/dri2.h
Kristian Høgsberg 3457ada
+++ b/hw/xfree86/dri2/dri2.h
Kristian Høgsberg 3457ada
@@ -58,6 +58,10 @@ typedef void		(*DRI2CopyRegionProcPtr)(DrawablePtr pDraw,
Kristian Høgsberg 3457ada
 						 RegionPtr pRegion,
Kristian Høgsberg 3457ada
 						 DRI2BufferPtr pDestBuffer,
Kristian Høgsberg 3457ada
 						 DRI2BufferPtr pSrcBuffer);
Kristian Høgsberg 3457ada
+typedef Bool		(*DRI2SwapBuffersProcPtr)(DrawablePtr pDraw,
Kristian Høgsberg 3457ada
+						  DRI2BufferPtr pFrontBuffer,
Kristian Høgsberg 3457ada
+						  DRI2BufferPtr pBackBuffer,
Kristian Høgsberg 3457ada
+						  void *data);
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
 typedef void		(*DRI2WaitProcPtr)(WindowPtr pWin,
Kristian Høgsberg 3457ada
 					   unsigned int sequence);
Kristian Høgsberg 3457ada
@@ -71,7 +75,7 @@ typedef void		(*DRI2DestroyBufferProcPtr)(DrawablePtr pDraw,
Kristian Høgsberg 3457ada
 /**
Kristian Høgsberg 3457ada
  * Version of the DRI2InfoRec structure defined in this header
Kristian Høgsberg 3457ada
  */
Kristian Høgsberg 3457ada
-#define DRI2INFOREC_VERSION 3
Kristian Høgsberg 3457ada
+#define DRI2INFOREC_VERSION 4
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
 typedef struct {
Kristian Høgsberg 3457ada
     unsigned int version;	/**< Version of this struct */
Kristian Høgsberg 3457ada
@@ -82,7 +86,7 @@ typedef struct {
Kristian Høgsberg 3457ada
     DRI2CreateBufferProcPtr	CreateBuffer;
Kristian Høgsberg 3457ada
     DRI2DestroyBufferProcPtr	DestroyBuffer;
Kristian Høgsberg 3457ada
     DRI2CopyRegionProcPtr	CopyRegion;
Kristian Høgsberg 3457ada
-    DRI2WaitProcPtr		Wait;
Kristian Høgsberg 3457ada
+    DRI2SwapBuffersProcPtr	SwapBuffers;
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
 }  DRI2InfoRec, *DRI2InfoPtr;
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
@@ -137,4 +141,8 @@ extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffersWithFormat(DrawablePtr pDraw,
Kristian Høgsberg 3457ada
 	int *width, int *height, unsigned int *attachments, int count,
Kristian Høgsberg 3457ada
 	int *out_count);
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
+extern _X_EXPORT int DRI2SwapBuffers(DrawablePtr pDrawable);
Kristian Høgsberg 3457ada
+extern _X_EXPORT Bool DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable);
Kristian Høgsberg 3457ada
+extern _X_EXPORT void DRI2SwapComplete(void *data);
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
 #endif
Kristian Høgsberg 3457ada
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
Kristian Høgsberg 3457ada
index 029dce8..9f5f389 100644
Kristian Høgsberg 3457ada
--- a/hw/xfree86/dri2/dri2ext.c
Kristian Høgsberg 3457ada
+++ b/hw/xfree86/dri2/dri2ext.c
Kristian Høgsberg 3457ada
@@ -80,7 +80,7 @@ ProcDRI2QueryVersion(ClientPtr client)
Kristian Høgsberg 3457ada
     rep.length = 0;
Kristian Høgsberg 3457ada
     rep.sequenceNumber = client->sequence;
Kristian Høgsberg 3457ada
     rep.majorVersion = 1;
Kristian Høgsberg 3457ada
-    rep.minorVersion = 1;
Kristian Høgsberg 3457ada
+    rep.minorVersion = 2;
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
     if (client->swapped) {
Kristian Høgsberg 3457ada
     	swaps(&rep.sequenceNumber, n);
Kristian Høgsberg 3457ada
@@ -253,6 +253,9 @@ ProcDRI2GetBuffers(ClientPtr client)
Kristian Høgsberg 3457ada
     if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
Kristian Høgsberg 3457ada
 	return status;
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
+    if (DRI2WaitSwap(client, pDrawable))
Kristian Høgsberg 3457ada
+	return client->noClientException;
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
     attachments = (unsigned int *) &stuff[1];
Kristian Høgsberg 3457ada
     buffers = DRI2GetBuffers(pDrawable, &width, &height,
Kristian Høgsberg 3457ada
 			     attachments, stuff->count, &count);
Kristian Høgsberg 3457ada
@@ -276,6 +279,9 @@ ProcDRI2GetBuffersWithFormat(ClientPtr client)
Kristian Høgsberg 3457ada
     if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
Kristian Høgsberg 3457ada
 	return status;
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
+    if (DRI2WaitSwap(client, pDrawable))
Kristian Høgsberg 3457ada
+	return client->noClientException;
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
     attachments = (unsigned int *) &stuff[1];
Kristian Høgsberg 3457ada
     buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height,
Kristian Høgsberg 3457ada
 				       attachments, stuff->count, &count);
Kristian Høgsberg 3457ada
@@ -322,6 +328,21 @@ ProcDRI2CopyRegion(ClientPtr client)
Kristian Høgsberg 3457ada
 }
Kristian Høgsberg 3457ada
 
Kristian Høgsberg 3457ada
 static int
Kristian Høgsberg 3457ada
+ProcDRI2SwapBuffers(ClientPtr client)
Kristian Høgsberg 3457ada
+{
Kristian Høgsberg 3457ada
+    REQUEST(xDRI2SwapBuffersReq);
Kristian Høgsberg 3457ada
+    DrawablePtr pDrawable;
Kristian Høgsberg 3457ada
+    int status;
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    REQUEST_SIZE_MATCH(xDRI2SwapBuffersReq);
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
Kristian Høgsberg 3457ada
+	return status;
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+    return DRI2SwapBuffers(pDrawable);
Kristian Høgsberg 3457ada
+}
Kristian Høgsberg 3457ada
+
Kristian Høgsberg 3457ada
+static int
Kristian Høgsberg 3457ada
 ProcDRI2Dispatch (ClientPtr client)
Kristian Høgsberg 3457ada
 {
Kristian Høgsberg 3457ada
     REQUEST(xReq);
Kristian Høgsberg 3457ada
@@ -349,6 +370,8 @@ ProcDRI2Dispatch (ClientPtr client)
Kristian Høgsberg 3457ada
 	return ProcDRI2CopyRegion(client);
Kristian Høgsberg 3457ada
     case X_DRI2GetBuffersWithFormat:
Kristian Høgsberg 3457ada
 	return ProcDRI2GetBuffersWithFormat(client);
Kristian Høgsberg 3457ada
+    case X_DRI2SwapBuffers:
Kristian Høgsberg 3457ada
+	return ProcDRI2SwapBuffers(client);
Kristian Høgsberg 3457ada
     default:
Kristian Høgsberg 3457ada
 	return BadRequest;
Kristian Høgsberg 3457ada
     }
Kristian Høgsberg 3457ada
-- 
cdde67c
1.6.0.6
Kristian Høgsberg 3457ada