[Intel-gfx] [PATCH] xserver: support DRI2 swapbuffers

Jesse Barnes jbarnes at virtuousgeek.org
Fri Feb 27 20:21:44 CET 2009


On Thursday, February 26, 2009 4:35:34 pm Jesse Barnes wrote:
> Found a bug in the AIGLX code; can't free the new buffers since we need
> them.

And another bug in the indirect case: if swapbuffers fails we should fall
back to a copyregion.  This should fix the old compiz case.

-- 
Jesse Barnes, Intel Open Source Technology Center

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 4e76c71..9d7d9bf 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -131,10 +131,26 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *drawable,
 static GLboolean
 __glXDRIdrawableSwapBuffers(__GLXdrawable *drawable)
 {
-    __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
+    __GLXDRIdrawable *priv = (__GLXDRIdrawable *) drawable;
+    DRI2BufferPtr buffers;
+    int i, count;
+
+    buffers = DRI2SwapBuffers(drawable->pDraw, &count);
+    if (!buffers) {
+	__glXDRIdrawableCopySubBuffer(drawable, 0, 0,
+				      priv->width, priv->height);
+	return TRUE;
+    }
+
+    for (i = 0; i < count; i++) {
+	priv->buffers[i].attachment = buffers[i].attachment;
+	priv->buffers[i].name = buffers[i].name;
+	priv->buffers[i].pitch = buffers[i].pitch;
+	priv->buffers[i].cpp = buffers[i].cpp;
+	priv->buffers[i].flags = buffers[i].flags;
+    }
 
-    __glXDRIdrawableCopySubBuffer(drawable, 0, 0,
-				  private->width, private->height);
+    priv->count = count;
 
     return TRUE;
 }
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 0f2e24b..1ee92dc 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -66,6 +66,7 @@ typedef struct _DRI2Screen {
     DRI2CreateBuffersProcPtr	 CreateBuffers;
     DRI2DestroyBuffersProcPtr	 DestroyBuffers;
     DRI2CopyRegionProcPtr	 CopyRegion;
+    DRI2SwapBuffersProcPtr	 SwapBuffers;
 
     HandleExposuresProcPtr       HandleExposures;
 } DRI2ScreenRec, *DRI2ScreenPtr;
@@ -188,6 +189,35 @@ DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
     return Success;
 }
 
+DRI2BufferPtr
+DRI2SwapBuffers(DrawablePtr pDraw, int *reply_count)
+{
+    DRI2ScreenPtr   ds = DRI2GetScreen(pDraw->pScreen);
+    DRI2DrawablePtr pPriv;
+    DRI2BufferPtr   buffers;
+
+    pPriv = DRI2GetDrawable(pDraw);
+    if (pPriv == NULL)
+	return NULL;
+
+    if (!ds->SwapBuffers)
+	return NULL;
+
+    /* Driver will give us a new set of buffers, so free the old ones */
+    buffers = (*ds->SwapBuffers)(pDraw, pPriv->buffers, pPriv->bufferCount);
+    if (!buffers) {
+	*reply_count = 0;
+	return NULL;
+    }
+
+    (*ds->DestroyBuffers)(pDraw, pPriv->buffers, pPriv->bufferCount);
+    pPriv->buffers = buffers;
+
+    *reply_count = pPriv->bufferCount;
+
+    return buffers;
+}
+
 void
 DRI2DestroyDrawable(DrawablePtr pDraw)
 {
@@ -264,6 +294,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..8cb9e94 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -54,6 +54,9 @@ typedef void		(*DRI2CopyRegionProcPtr)(DrawablePtr pDraw,
 						 RegionPtr pRegion,
 						 DRI2BufferPtr pDestBuffer,
 						 DRI2BufferPtr pSrcBuffer);
+typedef DRI2BufferPtr	(*DRI2SwapBuffersProcPtr)(DrawablePtr pDraw,
+						  DRI2BufferPtr buffers,
+						  int count);
 
 typedef void		(*DRI2WaitProcPtr)(WindowPtr pWin,
 					   unsigned int sequence);
@@ -67,6 +70,7 @@ typedef struct {
     DRI2CreateBuffersProcPtr	CreateBuffers;
     DRI2DestroyBuffersProcPtr	DestroyBuffers;
     DRI2CopyRegionProcPtr	CopyRegion;
+    DRI2SwapBuffersProcPtr      SwapBuffers;
     DRI2WaitProcPtr		Wait;
 
 }  DRI2InfoRec, *DRI2InfoPtr;
@@ -100,4 +104,6 @@ int DRI2CopyRegion(DrawablePtr pDraw,
 		   unsigned int dest,
 		   unsigned int src);
 
+DRI2BufferPtr DRI2SwapBuffers(DrawablePtr pDraw, int *count);
+
 #endif
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index 0a1dce4..5582a5f 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -269,6 +269,45 @@ ProcDRI2CopyRegion(ClientPtr client)
 }
 
 static int
+ProcDRI2SwapBuffers(ClientPtr client)
+{
+    REQUEST(xDRI2SwapBuffersReq);
+    xDRI2SwapBuffersReply rep;
+    DrawablePtr pDrawable;
+    DRI2BufferPtr buffers;
+    xDRI2Buffer buffer;
+    int status;
+    int i, count;
+
+    REQUEST_SIZE_MATCH(xDRI2SwapBuffersReq);
+
+    if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
+	return status;
+
+    buffers = DRI2SwapBuffers(pDrawable, &count);
+    if (!buffers) {
+	return BadAlloc;
+    }
+
+    rep.type = X_Reply;
+    rep.length = count * sizeof(xDRI2Buffer) / 4;
+    rep.count = count;
+    rep.sequenceNumber = client->sequence;
+    WriteToClient(client, sizeof(xDRI2GetBuffersReply), &rep);
+
+    for (i = 0; i < count; 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 +333,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