mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2026-02-16 08:30:28 +01:00
Only block swapping client not entire server in DRI2SwapBuffers
This commit is contained in:
parent
01a443b3b8
commit
219729033e
4 changed files with 89 additions and 22 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
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;
|
||||
if (DRI2FlipCheck(pDraw) &&
|
||||
(*ds->SwapBuffers)(pDraw, pDestBuffer, pSrcBuffer))
|
||||
{
|
||||
pPriv->swapPending = TRUE;
|
||||
return Success;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
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 FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
DRI2SwapComplete(DrawablePtr pDrawable)
|
||||
{
|
||||
DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable);
|
||||
|
||||
if (pPriv->blockedClient)
|
||||
AttendClient(pPriv->blockedClient);
|
||||
|
||||
pPriv->swapPending = FALSE;
|
||||
pPriv->blockedClient = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue