diff --git a/glx/glxdri2.c b/glx/glxdri2.c index 146ea82..3b5338b 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -70,6 +70,7 @@ struct __GLXDRIscreen { const __DRIcoreExtension *core; const __DRIdri2Extension *dri2; + const __DRI2flushExtension *flush; const __DRIcopySubBufferExtension *copySubBuffer; const __DRIswapControlExtension *swapControl; const __DRItexBufferExtension *texBuffer; @@ -135,10 +136,14 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *drawable, static GLboolean __glXDRIdrawableSwapBuffers(__GLXdrawable *drawable) { - __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; + __GLXDRIdrawable *priv = (__GLXDRIdrawable *) drawable; + __GLXDRIscreen *screen = priv->screen; + + if (!DRI2SwapBuffers(drawable->pDraw)) + return FALSE; - __glXDRIdrawableCopySubBuffer(drawable, 0, 0, - private->width, private->height); + if (screen->flush->flushInvalidate) + (*screen->flush->flushInvalidate)(priv->driDrawable); return TRUE; } diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 580383d..23e6467 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -70,6 +70,7 @@ typedef struct _DRI2Screen { DRI2CreateBufferProcPtr CreateBuffer; DRI2DestroyBufferProcPtr DestroyBuffer; DRI2CopyRegionProcPtr CopyRegion; + DRI2SwapBuffersProcPtr SwapBuffers; HandleExposuresProcPtr HandleExposures; } DRI2ScreenRec, *DRI2ScreenPtr; @@ -422,6 +423,49 @@ DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, return Success; } +Bool +DRI2SwapBuffers(DrawablePtr pDraw) +{ + DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); + DRI2DrawablePtr pPriv; + DRI2BufferPtr pDestBuffer, pSrcBuffer; + int i; + + pPriv = DRI2GetDrawable(pDraw); + if (pPriv == NULL) + return FALSE; + + pDestBuffer = NULL; + pSrcBuffer = NULL; + for (i = 0; i < pPriv->bufferCount; i++) + { + if (pPriv->buffers[i]->attachment == DRI2BufferFrontLeft) + pDestBuffer = (DRI2BufferPtr) pPriv->buffers[i]; + if (pPriv->buffers[i]->attachment == DRI2BufferBackLeft) + pSrcBuffer = (DRI2BufferPtr) pPriv->buffers[i]; + } + if (pSrcBuffer == NULL || pDestBuffer == NULL) + return FALSE; + + if (ds->SwapBuffers) { + if ((*ds->SwapBuffers)(pDraw, pDestBuffer, pSrcBuffer)) + return TRUE; + } + + BoxRec box; + RegionRec region; + + box.x1 = 0; + box.y1 = 0; + box.x2 = pDraw->width; + box.y2 = pDraw->height; + REGION_INIT(drawable->pDraw->pScreen, ®ion, &box, 0); + if (DRI2CopyRegion(pDraw, ®ion, DRI2BufferFrontLeft, DRI2BufferBackLeft) != Success) + return FALSE; + + return TRUE; +} + void DRI2DestroyDrawable(DrawablePtr pDraw) { @@ -538,6 +582,9 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) } ds->CopyRegion = info->CopyRegion; + if (info->version >= 3) + ds->SwapBuffers = info->SwapBuffers; + dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds); xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] Setup complete\n"); diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index f369267..e2784dd 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -67,6 +67,10 @@ typedef void (*DRI2CopyRegionProcPtr)(DrawablePtr pDraw, DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer); +typedef Bool (*DRI2SwapBuffersProcPtr)(DrawablePtr pDraw, + DRI2BufferPtr pFrontBuffer, + DRI2BufferPtr pBackBuffer); + typedef void (*DRI2WaitProcPtr)(WindowPtr pWin, unsigned int sequence); @@ -90,6 +94,7 @@ typedef struct { DRI2CreateBuffersProcPtr CreateBuffers; DRI2DestroyBuffersProcPtr DestroyBuffers; DRI2CopyRegionProcPtr CopyRegion; + DRI2SwapBuffersProcPtr SwapBuffers; DRI2WaitProcPtr Wait; /** @@ -153,4 +158,6 @@ extern _X_EXPORT DRI2Buffer2Ptr *DRI2GetBuffersWithFormat(DrawablePtr pDraw, int *width, int *height, unsigned int *attachments, int count, int *out_count); +extern _X_EXPORT Bool DRI2SwapBuffers(DrawablePtr pDraw); + #endif diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c index 3c06174..67b419b 100644 --- a/hw/xfree86/dri2/dri2ext.c +++ b/hw/xfree86/dri2/dri2ext.c @@ -81,7 +81,7 @@ ProcDRI2QueryVersion(ClientPtr client) rep.length = 0; rep.sequenceNumber = client->sequence; rep.majorVersion = 1; - rep.minorVersion = 1; + rep.minorVersion = 2; if (client->swapped) { swaps(&rep.sequenceNumber, n); @@ -323,6 +323,24 @@ ProcDRI2CopyRegion(ClientPtr client) } static int +ProcDRI2SwapBuffers(ClientPtr client) +{ + REQUEST(xDRI2SwapBuffersReq); + DrawablePtr pDrawable; + int status; + + REQUEST_SIZE_MATCH(xDRI2SwapBuffersReq); + + if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) + return status; + + if (!DRI2SwapBuffers(pDrawable)) + return BadAlloc; + + return client->noClientException; +} + +static int ProcDRI2Dispatch (ClientPtr client) { REQUEST(xReq); @@ -350,6 +368,8 @@ ProcDRI2Dispatch (ClientPtr client) return ProcDRI2CopyRegion(client); case X_DRI2GetBuffersWithFormat: return ProcDRI2GetBuffersWithFormat(client); + case X_DRI2SwapBuffers: + return ProcDRI2SwapBuffers(client); default: return BadRequest; }