xserver: Branch 'dri2-swapbuffers'
Kristian Høgsberg
krh at kemper.freedesktop.org
Fri Jul 17 16:27:14 PDT 2009
glx/glxdri2.c | 2 -
hw/xfree86/dri2/dri2.c | 92 ++++++++++++++++++++++++++++++++++++++--------
hw/xfree86/dri2/dri2.h | 4 +-
hw/xfree86/dri2/dri2ext.c | 11 +++--
4 files changed, 88 insertions(+), 21 deletions(-)
New commits:
commit c69e1eed41b64ffe96e765f70002e70232bcff39
Author: Kristian Høgsberg <krh at redhat.com>
Date: Fri Jul 17 11:26:37 2009 -0400
Only block swapping client not entire server in DRI2SwapBuffers
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 90dca30..6fb4cf1 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 1ed2814..787cdd7 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 "xf86.h"
@@ -55,7 +56,8 @@ typedef struct _DRI2Drawable {
int height;
DRI2BufferPtr *buffers;
int bufferCount;
- unsigned int pendingSequence;
+ unsigned int swapPending;
+ ClientPtr blockedClient;
} DRI2DrawableRec, *DRI2DrawablePtr;
typedef struct _DRI2Screen {
@@ -119,6 +121,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)
{
@@ -338,17 +342,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;
@@ -360,22 +390,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 e330fe9..8cf2308 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 9f5a196..9f5f389 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -253,6 +253,9 @@ ProcDRI2GetBuffers(ClientPtr client)
if (!validDrawable(client, stuff->drawable, &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);
@@ -276,6 +279,9 @@ ProcDRI2GetBuffersWithFormat(ClientPtr client)
if (!validDrawable(client, stuff->drawable, &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);
@@ -333,10 +339,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
More information about the xorg-commit
mailing list