diff options
author | Rob Clark <rob@ti.com> | 2012-04-20 19:13:57 -0500 |
---|---|---|
committer | Rob Clark <rob@ti.com> | 2012-04-20 19:19:45 -0500 |
commit | 67b875f348fe67289d00b70526c4cf6d82280d29 (patch) | |
tree | f8998c3c6df2307656dbeeda1165588ff9661e15 | |
parent | 1272ef49f75295d462799910007cb07367c1d35a (diff) |
dri2: block close-screen until flips complete0.3.0
If CloseScreen happens while we are waiting for a page_flip event, we
need to block the CloseScreen until after the page_flip is processed
to avoid deref'ing the screen ptr after the screen is closed.
-rw-r--r-- | src/drmmode_display.c | 13 | ||||
-rw-r--r-- | src/omap_dri2.c | 10 | ||||
-rw-r--r-- | src/omap_driver.h | 4 |
3 files changed, 24 insertions, 3 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 371f54e..0dbc01d 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1295,11 +1295,11 @@ drmmode_uevent_fini(ScrnInfoPtr pScrn) static void drmmode_wakeup_handler(pointer data, int err, pointer p) { - ScrnInfoPtr scrn = data; - drmmode_ptr drmmode = drmmode_from_scrn(scrn); + ScrnInfoPtr pScrn = data; + drmmode_ptr drmmode = drmmode_from_scrn(pScrn); fd_set *read_mask = p; - if (scrn == NULL || err < 0) + if (pScrn == NULL || err < 0) return; if (FD_ISSET(drmmode->fd, read_mask)) @@ -1307,6 +1307,13 @@ drmmode_wakeup_handler(pointer data, int err, pointer p) } void +drmmode_wait_for_event(ScrnInfoPtr pScrn) +{ + drmmode_ptr drmmode = drmmode_from_scrn(pScrn); + drmHandleEvent(drmmode->fd, &event_context); +} + +void drmmode_screen_init(ScrnInfoPtr pScrn) { drmmode_ptr drmmode = drmmode_from_scrn(pScrn); diff --git a/src/omap_dri2.c b/src/omap_dri2.c index db422ef..1ab48e0 100644 --- a/src/omap_dri2.c +++ b/src/omap_dri2.c @@ -354,6 +354,7 @@ OMAPDRI2SwapComplete(OMAPDRISwapCmd *cmd) { ScreenPtr pScreen = cmd->pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + OMAPPtr pOMAP = OMAPPTR(pScrn); DrawablePtr pDraw = NULL; int status; @@ -375,6 +376,7 @@ OMAPDRI2SwapComplete(OMAPDRISwapCmd *cmd) */ OMAPDRI2DestroyBuffer(pDraw, cmd->pSrcBuffer); OMAPDRI2DestroyBuffer(pDraw, cmd->pDstBuffer); + pOMAP->pending_flips--; free(cmd); } @@ -399,6 +401,7 @@ OMAPDRI2ScheduleSwap(ClientPtr client, DrawablePtr pDraw, { ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + OMAPPtr pOMAP = OMAPPTR(pScrn); OMAPDRI2BufferPtr src = OMAPBUF(pSrcBuffer); OMAPDRI2BufferPtr dst = OMAPBUF(pDstBuffer); OMAPDRISwapCmd *cmd = calloc(1, sizeof(*cmd)); @@ -418,6 +421,7 @@ OMAPDRI2ScheduleSwap(ClientPtr client, DrawablePtr pDraw, */ OMAPDRI2ReferenceBuffer(pSrcBuffer); OMAPDRI2ReferenceBuffer(pDstBuffer); + pOMAP->pending_flips++; if (src->fb_id && dst->fb_id) { DEBUG_MSG("can flip: %d -> %d", src->fb_id, dst->fb_id); @@ -506,5 +510,11 @@ OMAPDRI2ScreenInit(ScreenPtr pScreen) void OMAPDRI2CloseScreen(ScreenPtr pScreen) { + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + OMAPPtr pOMAP = OMAPPTR(pScrn); + while (pOMAP->pending_flips > 0) { + DEBUG_MSG("waiting.."); + drmmode_wait_for_event(pScrn); + } DRI2CloseScreen(pScreen); } diff --git a/src/omap_driver.h b/src/omap_driver.h index 028545c..ede45e4 100644 --- a/src/omap_driver.h +++ b/src/omap_driver.h @@ -159,6 +159,9 @@ typedef struct _OMAPRec XF86VideoAdaptorPtr textureAdaptor; + /** Flips we are waiting for: */ + int pending_flips; + } OMAPRec, *OMAPPtr; /* @@ -219,6 +222,7 @@ void drmmode_screen_fini(ScrnInfoPtr pScrn); void drmmode_adjust_frame(ScrnInfoPtr pScrn, int x, int y, int flags); void drmmode_remove_fb(ScrnInfoPtr pScrn); Bool drmmode_page_flip(DrawablePtr draw, uint32_t fb_id, void *priv); +void drmmode_wait_for_event(ScrnInfoPtr pScrn); Bool drmmode_cursor_init(ScreenPtr pScreen); |