[Intel-gfx] [PATCH] xserver: add DRI2 swapbuffers support
Jesse Barnes
jbarnes at virtuousgeek.org
Wed Apr 15 00:25:56 CEST 2009
Add support to the X server for the new DRI2 swapbuffers request. This
requires a new driver callback, SwapBuffers, which takes care of
performing the swap and allocating new buffers if necessary.
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 4544a2c..af6755b 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -133,10 +133,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