diff options
author | Kristian Høgsberg <krh@redhat.com> | 2009-07-17 11:26:37 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-10-29 14:05:09 -0700 |
commit | 219729033efb2d970bc8c6b3f98006b6ebddcdfe (patch) | |
tree | 0cb00af6f81badd096cf823d13cacc2600015ed1 | |
parent | 01a443b3b85cf5013f969126a57358c9f9704175 (diff) | |
download | xserver-219729033efb2d970bc8c6b3f98006b6ebddcdfe.tar.gz |
Only block swapping client not entire server in DRI2SwapBuffers
-rw-r--r-- | glx/glxdri2.c | 2 | ||||
-rw-r--r-- | hw/xfree86/dri2/dri2.c | 92 | ||||
-rw-r--r-- | hw/xfree86/dri2/dri2.h | 4 | ||||
-rw-r--r-- | hw/xfree86/dri2/dri2ext.c | 11 |
4 files changed, 88 insertions, 21 deletions
diff --git a/glx/glxdri2.c b/glx/glxdri2.c index 1d51ce6f8..63462a54c 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -175,7 +175,7 @@ __glXDRIdrawableSwapBuffers(__GLXdrawable *drawable) (*screen->flush->flushInvalidate)(priv->driDrawable); - if (!DRI2SwapBuffers(drawable->pDraw)) + if (DRI2SwapBuffers(drawable->pDraw) != Success) return FALSE; return TRUE; diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 22ac9a5e7..fc1d25603 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -38,6 +38,7 @@ #include "xf86Module.h" #include "scrnintstr.h" #include "windowstr.h" +#include "dixstruct.h" #include "dri2.h" #include "xf86VGAarbiter.h" @@ -56,7 +57,8 @@ typedef struct _DRI2Drawable { int height; DRI2BufferPtr *buffers; int bufferCount; - unsigned int pendingSequence; + unsigned int swapPending; + ClientPtr blockedClient; } DRI2DrawableRec, *DRI2DrawablePtr; typedef struct _DRI2Screen { @@ -120,6 +122,8 @@ DRI2CreateDrawable(DrawablePtr pDraw) pPriv->height = pDraw->height; pPriv->buffers = NULL; pPriv->bufferCount = 0; + pPriv->swapPending = FALSE; + pPriv->blockedClient = NULL; if (pDraw->type == DRAWABLE_WINDOW) { @@ -339,17 +343,43 @@ DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, return Success; } -Bool +static Bool +DRI2FlipCheck(DrawablePtr pDraw) +{ + ScreenPtr pScreen = pDraw->pScreen; + WindowPtr pWin; + PixmapPtr pWinPixmap; + + if (pDraw->type == DRAWABLE_PIXMAP) + return TRUE; + + pWin = (WindowPtr) pDraw; + pWinPixmap = pScreen->GetWindowPixmap(pWin); + if (pDraw->width != pWinPixmap->drawable.width) + return FALSE; + if (pDraw->height != pWinPixmap->drawable.height) + return FALSE; + if (pDraw->depth != pWinPixmap->drawable.depth) + return FALSE; + if (!REGION_EQUAL(pScreen, &pWin->clipList, &pWin->winSize)) + return FALSE; + + return TRUE; +} + +int DRI2SwapBuffers(DrawablePtr pDraw) { DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); DRI2DrawablePtr pPriv; DRI2BufferPtr pDestBuffer, pSrcBuffer; int i; + BoxRec box; + RegionRec region; pPriv = DRI2GetDrawable(pDraw); if (pPriv == NULL) - return FALSE; + return BadDrawable; pDestBuffer = NULL; pSrcBuffer = NULL; @@ -361,22 +391,54 @@ DRI2SwapBuffers(DrawablePtr pDraw) pSrcBuffer = pPriv->buffers[i]; } if (pSrcBuffer == NULL || pDestBuffer == NULL) - return FALSE; + return BadValue; - if (!(*ds->SwapBuffers)(pDraw, pDestBuffer, pSrcBuffer)) { - BoxRec box; - RegionRec region; + if (DRI2FlipCheck(pDraw) && + (*ds->SwapBuffers)(pDraw, pDestBuffer, pSrcBuffer)) + { + pPriv->swapPending = TRUE; + return Success; + } - 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; + box.x1 = 0; + box.y1 = 0; + box.x2 = pDraw->width; + box.y2 = pDraw->height; + REGION_INIT(drawable->pDraw->pScreen, ®ion, &box, 0); + + return DRI2CopyRegion(pDraw, ®ion, + DRI2BufferFrontLeft, DRI2BufferBackLeft); +} + +Bool +DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable) +{ + DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable); + + /* If we're currently waiting for a swap on this drawable, reset + * the request and suspend the client. We only support one + * blocked client per drawable. */ + if (pPriv->swapPending && pPriv->blockedClient == NULL) { + ResetCurrentRequest(client); + client->sequence--; + IgnoreClient(client); + pPriv->blockedClient = client; + return TRUE; } - return TRUE; + return FALSE; +} + +void +DRI2SwapComplete(DrawablePtr pDrawable) +{ + DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable); + + if (pPriv->blockedClient) + AttendClient(pPriv->blockedClient); + + pPriv->swapPending = FALSE; + pPriv->blockedClient = NULL; } void diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index e330fe930..8cf23085e 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -140,6 +140,8 @@ extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffersWithFormat(DrawablePtr pDraw, int *width, int *height, unsigned int *attachments, int count, int *out_count); -extern _X_EXPORT Bool DRI2SwapBuffers(DrawablePtr pDraw); +extern _X_EXPORT int DRI2SwapBuffers(DrawablePtr pDraw); +extern _X_EXPORT Bool DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable); +extern _X_EXPORT void DRI2SwapComplete(DrawablePtr pDrawable); #endif diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c index b2bb5d0a6..666fe729c 100644 --- a/hw/xfree86/dri2/dri2ext.c +++ b/hw/xfree86/dri2/dri2ext.c @@ -259,6 +259,9 @@ ProcDRI2GetBuffers(ClientPtr client) &pDrawable, &status)) return status; + if (DRI2WaitSwap(client, pDrawable)) + return client->noClientException; + attachments = (unsigned int *) &stuff[1]; buffers = DRI2GetBuffers(pDrawable, &width, &height, attachments, stuff->count, &count); @@ -283,6 +286,9 @@ ProcDRI2GetBuffersWithFormat(ClientPtr client) &pDrawable, &status)) return status; + if (DRI2WaitSwap(client, pDrawable)) + return client->noClientException; + attachments = (unsigned int *) &stuff[1]; buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height, attachments, stuff->count, &count); @@ -341,10 +347,7 @@ ProcDRI2SwapBuffers(ClientPtr client) if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) return status; - if (!DRI2SwapBuffers(pDrawable)) - return BadAlloc; - - return client->noClientException; + return DRI2SwapBuffers(pDrawable); } static int |