summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Clark <rob@ti.com>2012-04-20 19:13:57 -0500
committerRob Clark <rob@ti.com>2012-04-20 19:19:45 -0500
commit67b875f348fe67289d00b70526c4cf6d82280d29 (patch)
treef8998c3c6df2307656dbeeda1165588ff9661e15
parent1272ef49f75295d462799910007cb07367c1d35a (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.c13
-rw-r--r--src/omap_dri2.c10
-rw-r--r--src/omap_driver.h4
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);