Add support for the new DRI2 swapbuffers request by supporting the protocol and adding a new driver hook to perform the swap. If it fails we'll fall back to blitting.
Signed-off-by: Jesse Barnes <jbar...@virtuousgeek.org> diff --git a/glx/glxdri2.c b/glx/glxdri2.c index 4e76c71..b76a786 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -131,10 +131,25 @@ __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) + return FALSE; + + 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; + } + + priv->count = count; - __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..375a13d 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,32 @@ 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; + + /* 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 +291,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; } ------------------------------------------------------------------------------ Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H -- _______________________________________________ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel