[Intel-gfx] [PATCH] xserver: support DRI2 buffer swaps

Jesse Barnes jbarnes at virtuousgeek.org
Fri Feb 13 01:56:26 CET 2009


Support the new protocol requests, and expose the DRI2Drawable to drivers, so
they can poke at it for SwapBuffers requests.

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 4e76c71..892d07f 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -131,10 +131,27 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *drawable,
 static GLboolean
 __glXDRIdrawableSwapBuffers(__GLXdrawable *drawable)
 {
-    __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
+    __GLXDRIdrawable *priv = (__GLXDRIdrawable *) drawable;
+    DRI2BufferPtr buffers;
+    int i, j;
+
+    buffers = DRI2SwapBuffers(drawable->pDraw);
+    if (!buffers)
+	return FALSE;
+
+    /* Update the front & back buffer objects */
+    for (j = 0; j < 2; j++) {
+	    for (i = 0; i < priv->count; i++) {
+		    if (priv->buffers[i].attachment == buffers[j].attachment) {
+			    priv->buffers[i].name = buffers[j].name;
+			    priv->buffers[i].pitch = buffers[j].pitch;
+			    priv->buffers[i].cpp = buffers[j].cpp;
+			    priv->buffers[i].flags = buffers[j].flags;
+		    }
+	    }
+    }
 
-    __glXDRIdrawableCopySubBuffer(drawable, 0, 0,
-				  private->width, private->height);
+    xfree(buffers);
 
     return TRUE;
 }
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 0f2e24b..52dc8c7 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -49,15 +49,6 @@ static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKeyIndex;
 static int dri2PixmapPrivateKeyIndex;
 static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKeyIndex;
 
-typedef struct _DRI2Drawable {
-    unsigned int	 refCount;
-    int			 width;
-    int			 height;
-    DRI2BufferPtr	 buffers;
-    int			 bufferCount;
-    unsigned int	 pendingSequence;
-} DRI2DrawableRec, *DRI2DrawablePtr;
-
 typedef struct _DRI2Screen {
     const char			*driverName;
     const char			*deviceName;
@@ -66,6 +57,7 @@ typedef struct _DRI2Screen {
     DRI2CreateBuffersProcPtr	 CreateBuffers;
     DRI2DestroyBuffersProcPtr	 DestroyBuffers;
     DRI2CopyRegionProcPtr	 CopyRegion;
+    DRI2SwapBuffersProcPtr	 SwapBuffers;
 
     HandleExposuresProcPtr       HandleExposures;
 } DRI2ScreenRec, *DRI2ScreenPtr;
@@ -76,7 +68,7 @@ DRI2GetScreen(ScreenPtr pScreen)
     return dixLookupPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey);
 }
 
-static DRI2DrawablePtr
+DRI2DrawablePtr
 DRI2GetDrawable(DrawablePtr pDraw)
 {
     WindowPtr		  pWin;
@@ -188,6 +180,20 @@ DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
     return Success;
 }
 
+DRI2BufferPtr
+DRI2SwapBuffers(DrawablePtr pDraw)
+{
+    DRI2ScreenPtr   ds = DRI2GetScreen(pDraw->pScreen);
+    DRI2DrawablePtr pPriv;
+
+    /* FIXME: make sure drawable is double buffered */
+    pPriv = DRI2GetDrawable(pDraw);
+    if (pPriv == NULL)
+	return BadDrawable;
+
+    return (*ds->SwapBuffers)(pDraw);
+}
+
 void
 DRI2DestroyDrawable(DrawablePtr pDraw)
 {
@@ -264,6 +270,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
     ds->CreateBuffers  = info->CreateBuffers;
     ds->DestroyBuffers = info->DestroyBuffers;
     ds->CopyRegion     = info->CopyRegion;
+    ds->SwapBuffers    = info->SwapBuffers;
 
     dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
 
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index 5e7fd65..a075ddc 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -44,6 +44,15 @@ typedef struct {
     void *driverPrivate;
 } DRI2BufferRec, *DRI2BufferPtr;
 
+typedef struct _DRI2Drawable {
+    unsigned int	 refCount;
+    int			 width;
+    int			 height;
+    DRI2BufferPtr	 buffers;
+    int			 bufferCount;
+    unsigned int	 pendingSequence;
+} DRI2DrawableRec, *DRI2DrawablePtr;
+
 typedef DRI2BufferPtr	(*DRI2CreateBuffersProcPtr)(DrawablePtr pDraw,
 						    unsigned int *attachments,
 						    int count);
@@ -54,6 +63,7 @@ typedef void		(*DRI2CopyRegionProcPtr)(DrawablePtr pDraw,
 						 RegionPtr pRegion,
 						 DRI2BufferPtr pDestBuffer,
 						 DRI2BufferPtr pSrcBuffer);
+typedef DRI2BufferPtr	(*DRI2SwapBuffersProcPtr)(DrawablePtr pDraw);
 
 typedef void		(*DRI2WaitProcPtr)(WindowPtr pWin,
 					   unsigned int sequence);
@@ -67,10 +77,13 @@ typedef struct {
     DRI2CreateBuffersProcPtr	CreateBuffers;
     DRI2DestroyBuffersProcPtr	DestroyBuffers;
     DRI2CopyRegionProcPtr	CopyRegion;
+    DRI2SwapBuffersProcPtr      SwapBuffers;
     DRI2WaitProcPtr		Wait;
 
 }  DRI2InfoRec, *DRI2InfoPtr;
 
+DRI2DrawablePtr DRI2GetDrawable(DrawablePtr pDraw);
+
 Bool DRI2ScreenInit(ScreenPtr	pScreen,
 		    DRI2InfoPtr info);
 
@@ -100,4 +113,6 @@ int DRI2CopyRegion(DrawablePtr pDraw,
 		   unsigned int dest,
 		   unsigned int src);
 
+DRI2BufferPtr DRI2SwapBuffers(DrawablePtr pDraw);
+
 #endif
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index 0a1dce4..d571525 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -269,6 +269,43 @@ ProcDRI2CopyRegion(ClientPtr client)
 }
 
 static int
+ProcDRI2SwapBuffers(ClientPtr client)
+{
+    REQUEST(xDRI2SwapBuffersReq);
+    xDRI2SwapBuffersReply rep;
+    DrawablePtr pDrawable;
+    DRI2BufferPtr buffers;
+    xDRI2Buffer buffer;
+    int status;
+    int i;
+
+    REQUEST_SIZE_MATCH(xDRI2SwapBuffersReq);
+
+    if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
+	return status;
+
+    buffers = DRI2SwapBuffers(pDrawable);
+    if (status != Success)
+	return status;
+
+    rep.type = X_Reply;
+    rep.length = 2 * sizeof(xDRI2Buffer) / 4;
+    rep.sequenceNumber = client->sequence;
+    WriteToClient(client, sizeof(xDRI2GetBuffersReply), &rep);
+
+    for (i = 0; i < 2; i++) {
+	buffer.attachment = buffers[i].attachment;
+	buffer.name = buffers[i].name;
+	buffer.pitch = buffers[i].pitch;
+	buffer.cpp = buffers[i].cpp;
+	buffer.flags = buffers[i].flags;
+	WriteToClient(client, sizeof(xDRI2Buffer), &buffer);
+    }
+
+    return client->noClientException;
+}
+
+static int
 ProcDRI2Dispatch (ClientPtr client)
 {
     REQUEST(xReq);
@@ -294,6 +331,8 @@ ProcDRI2Dispatch (ClientPtr client)
 	return ProcDRI2GetBuffers(client);
     case X_DRI2CopyRegion:
 	return ProcDRI2CopyRegion(client);
+    case X_DRI2SwapBuffers:
+	return ProcDRI2SwapBuffers(client);
     default:
 	return BadRequest;
     }



More information about the Intel-gfx mailing list