diff options
author | Rob Clark <rob@ti.com> | 2012-08-06 16:17:17 -0500 |
---|---|---|
committer | Rob Clark <rob@ti.com> | 2012-08-06 16:17:17 -0500 |
commit | 8bb109f8b021a93cdabc44cd16777201ad3690cd (patch) | |
tree | d4aa44971e78877aad9ceceb5fd17a469c567d08 /src/omap_dri2.c | |
parent | 4d17efef3fab75e3ce3035c59289c48bd9cf77de (diff) |
dri2: fix multi-drawable flip confusion
A flip pending on the fullscreen drawable shouldn't effect a swap on
a windowed drawable. This shows up if using a GL compositing window
manager (like compiz) compositing a 3d app. We still need to keep
track of pending flips globally (per display), but use a per-drawable
counter in the decision to queue up.
Signed-off-by: Rob Clark <rob@ti.com>
Diffstat (limited to 'src/omap_dri2.c')
-rw-r--r-- | src/omap_dri2.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/src/omap_dri2.c b/src/omap_dri2.c index 1e4edd3..53db098 100644 --- a/src/omap_dri2.c +++ b/src/omap_dri2.c @@ -96,6 +96,9 @@ typedef struct { */ OMAPDRISwapCmd *cmd; + /* pending swaps on this drawable (which might or might not be flips) */ + int pending_swaps; + } OMAPDRI2DrawableRec, *OMAPDRI2DrawablePtr; static int @@ -426,6 +429,7 @@ OMAPDRI2SwapDispatch(DrawablePtr pDraw, OMAPDRISwapCmd *cmd) /* if we can flip, do so: */ if (canflip(pDraw) && drmmode_page_flip(pDraw, src->pPixmap, cmd)) { + OMAPPTR(pScrn)->pending_page_flips++; cmd->type = DRI2_FLIP_COMPLETE; } else if (canexchange(pDraw, cmd->pSrcBuffer, cmd->pDstBuffer)) { /* we can get away w/ pointer swap.. yah! */ @@ -480,13 +484,15 @@ OMAPDRI2SwapComplete(OMAPDRISwapCmd *cmd) { ScreenPtr pScreen = cmd->pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - OMAPPtr pOMAP = OMAPPTR(pScrn); DrawablePtr pDraw = NULL; int status; DEBUG_MSG("%s complete: %d -> %d", swap_names[cmd->type], cmd->pSrcBuffer->attachment, cmd->pDstBuffer->attachment); + if (cmd->type == DRI2_FLIP_COMPLETE) + OMAPPTR(pScrn)->pending_page_flips--; + status = dixLookupDrawable(&pDraw, cmd->draw_id, serverClient, M_ANY, DixWriteAccess); @@ -501,13 +507,13 @@ OMAPDRI2SwapComplete(OMAPDRISwapCmd *cmd) OMAPDRI2SwapDispatch(pDraw, pPriv->cmd); pPriv->cmd = NULL; } + pPriv->pending_swaps--; } /* drop extra refcnt we obtained prior to swap: */ OMAPDRI2DestroyBuffer(pDraw, cmd->pSrcBuffer); OMAPDRI2DestroyBuffer(pDraw, cmd->pDstBuffer); - pOMAP->pending_swaps--; free(cmd); } @@ -532,7 +538,7 @@ OMAPDRI2ScheduleSwap(ClientPtr client, DrawablePtr pDraw, { ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - OMAPPtr pOMAP = OMAPPTR(pScrn); + OMAPDRI2DrawablePtr pPriv = OMAPDRI2GetDrawable(pDraw); OMAPDRISwapCmd *cmd = calloc(1, sizeof(*cmd)); cmd->client = client; @@ -549,14 +555,17 @@ OMAPDRI2ScheduleSwap(ClientPtr client, DrawablePtr pDraw, OMAPDRI2ReferenceBuffer(pSrcBuffer); OMAPDRI2ReferenceBuffer(pDstBuffer); - pOMAP->pending_swaps++; + pPriv->pending_swaps++; - if (pOMAP->pending_swaps > 1) { + if (pPriv->pending_swaps > 1) { /* if we already have a pending swap, then just queue this * one up: */ - OMAPDRI2DrawablePtr pPriv = OMAPDRI2GetDrawable(pDraw); - assert(!pPriv->cmd); + if (pPriv->cmd) { + ERROR_MSG("already pending a flip!"); + pPriv->pending_swaps--; + return FALSE; + } pPriv->cmd = cmd; } else { OMAPDRI2SwapDispatch(pDraw, cmd); @@ -639,7 +648,7 @@ OMAPDRI2CloseScreen(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; OMAPPtr pOMAP = OMAPPTR(pScrn); - while (pOMAP->pending_swaps > 0) { + while (pOMAP->pending_page_flips > 0) { DEBUG_MSG("waiting.."); drmmode_wait_for_event(pScrn); } |