xserver: Branch 'dri2-swapbuffers'

Kristian Høgsberg krh at kemper.freedesktop.org
Fri Jul 17 16:27:14 PDT 2009


 glx/glxdri2.c             |    2 -
 hw/xfree86/dri2/dri2.c    |   92 ++++++++++++++++++++++++++++++++++++++--------
 hw/xfree86/dri2/dri2.h    |    4 +-
 hw/xfree86/dri2/dri2ext.c |   11 +++--
 4 files changed, 88 insertions(+), 21 deletions(-)

New commits:
commit c69e1eed41b64ffe96e765f70002e70232bcff39
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Fri Jul 17 11:26:37 2009 -0400

    Only block swapping client not entire server in DRI2SwapBuffers

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 90dca30..6fb4cf1 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -175,7 +175,7 @@ __glXDRIdrawableSwapBuffers(__GLXdrawable *drawable)
 
     (*screen->flush->flushInvalidate)(priv->driDrawable);
 
-    if (!DRI2SwapBuffers(drawable->pDraw))
+    if (DRI2SwapBuffers(drawable->pDraw) != Success)
 	return FALSE;
 
     return TRUE;
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 1ed2814..787cdd7 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -38,6 +38,7 @@
 #include "xf86Module.h"
 #include "scrnintstr.h"
 #include "windowstr.h"
+#include "dixstruct.h"
 #include "dri2.h"
 
 #include "xf86.h"
@@ -55,7 +56,8 @@ typedef struct _DRI2Drawable {
     int			 height;
     DRI2BufferPtr	*buffers;
     int			 bufferCount;
-    unsigned int	 pendingSequence;
+    unsigned int	 swapPending;
+    ClientPtr		 blockedClient;
 } DRI2DrawableRec, *DRI2DrawablePtr;
 
 typedef struct _DRI2Screen {
@@ -119,6 +121,8 @@ DRI2CreateDrawable(DrawablePtr pDraw)
     pPriv->height = pDraw->height;
     pPriv->buffers = NULL;
     pPriv->bufferCount = 0;
+    pPriv->swapPending = FALSE;
+    pPriv->blockedClient = NULL;
 
     if (pDraw->type == DRAWABLE_WINDOW)
     {
@@ -338,17 +342,43 @@ DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
     return Success;
 }
 
-Bool
+static Bool
+DRI2FlipCheck(DrawablePtr pDraw)
+{
+    ScreenPtr pScreen = pDraw->pScreen;
+    WindowPtr pWin;
+    PixmapPtr pWinPixmap;
+
+    if (pDraw->type == DRAWABLE_PIXMAP)
+	return TRUE;
+
+    pWin = (WindowPtr) pDraw;
+    pWinPixmap = pScreen->GetWindowPixmap(pWin);
+    if (pDraw->width != pWinPixmap->drawable.width)
+	return FALSE;
+    if (pDraw->height != pWinPixmap->drawable.height)
+	return FALSE;
+    if (pDraw->depth != pWinPixmap->drawable.depth)
+	return FALSE;
+    if (!REGION_EQUAL(pScreen, &pWin->clipList, &pWin->winSize))
+	return FALSE;
+
+    return TRUE;
+}
+
+int
 DRI2SwapBuffers(DrawablePtr pDraw)
 {
     DRI2ScreenPtr   ds = DRI2GetScreen(pDraw->pScreen);
     DRI2DrawablePtr pPriv;
     DRI2BufferPtr   pDestBuffer, pSrcBuffer;
     int		    i;
+    BoxRec	    box;
+    RegionRec	    region;
 
     pPriv = DRI2GetDrawable(pDraw);
     if (pPriv == NULL)
-	return FALSE;
+	return BadDrawable;
 
     pDestBuffer = NULL;
     pSrcBuffer = NULL;
@@ -360,22 +390,54 @@ DRI2SwapBuffers(DrawablePtr pDraw)
 	    pSrcBuffer = pPriv->buffers[i];
     }
     if (pSrcBuffer == NULL || pDestBuffer == NULL)
-	return FALSE;
+	return BadValue;
 
-    if (!(*ds->SwapBuffers)(pDraw, pDestBuffer, pSrcBuffer)) {
-	BoxRec box;
-	RegionRec region;
+    if (DRI2FlipCheck(pDraw) &&
+	(*ds->SwapBuffers)(pDraw, pDestBuffer, pSrcBuffer))
+    {
+	pPriv->swapPending = TRUE;
+	return Success;
+    }
 
-	box.x1 = 0;
-	box.y1 = 0;
-	box.x2 = pDraw->width;
-	box.y2 = pDraw->height;
-	REGION_INIT(drawable->pDraw->pScreen, &region, &box, 0);
-	if (DRI2CopyRegion(pDraw, &region, DRI2BufferFrontLeft, DRI2BufferBackLeft) != Success)
-	    return FALSE;
+    box.x1 = 0;
+    box.y1 = 0;
+    box.x2 = pDraw->width;
+    box.y2 = pDraw->height;
+    REGION_INIT(drawable->pDraw->pScreen, &region, &box, 0);
+    
+    return DRI2CopyRegion(pDraw, &region,
+			  DRI2BufferFrontLeft, DRI2BufferBackLeft);
+}
+
+Bool
+DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable)
+{
+    DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable);
+
+    /* If we're currently waiting for a swap on this drawable, reset
+     * the request and suspend the client.  We only support one
+     * blocked client per drawable. */
+    if (pPriv->swapPending && pPriv->blockedClient == NULL) {
+	ResetCurrentRequest(client);
+	client->sequence--;
+	IgnoreClient(client);
+	pPriv->blockedClient = client;
+	return TRUE;
     }
 
-    return TRUE;
+    return FALSE;
+}
+
+void
+DRI2SwapComplete(DrawablePtr pDrawable)
+{
+    DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable);
+
+    if (pPriv->blockedClient)
+	AttendClient(pPriv->blockedClient);
+
+    pPriv->swapPending = FALSE;
+    pPriv->blockedClient = NULL;
 }
 
 void
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index e330fe9..8cf2308 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -140,6 +140,8 @@ extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffersWithFormat(DrawablePtr pDraw,
 	int *width, int *height, unsigned int *attachments, int count,
 	int *out_count);
 
-extern _X_EXPORT Bool DRI2SwapBuffers(DrawablePtr pDraw);
+extern _X_EXPORT int DRI2SwapBuffers(DrawablePtr pDraw);
+extern _X_EXPORT Bool DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable);
+extern _X_EXPORT void DRI2SwapComplete(DrawablePtr pDrawable);
 
 #endif
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index 9f5a196..9f5f389 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -253,6 +253,9 @@ ProcDRI2GetBuffers(ClientPtr client)
     if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
 	return status;
 
+    if (DRI2WaitSwap(client, pDrawable))
+	return client->noClientException;
+
     attachments = (unsigned int *) &stuff[1];
     buffers = DRI2GetBuffers(pDrawable, &width, &height,
 			     attachments, stuff->count, &count);
@@ -276,6 +279,9 @@ ProcDRI2GetBuffersWithFormat(ClientPtr client)
     if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
 	return status;
 
+    if (DRI2WaitSwap(client, pDrawable))
+	return client->noClientException;
+
     attachments = (unsigned int *) &stuff[1];
     buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height,
 				       attachments, stuff->count, &count);
@@ -333,10 +339,7 @@ ProcDRI2SwapBuffers(ClientPtr client)
     if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
 	return status;
 
-    if (!DRI2SwapBuffers(pDrawable))
-	return BadAlloc;
-
-    return client->noClientException;
+    return DRI2SwapBuffers(pDrawable);
 }
 
 static int


More information about the xorg-commit mailing list