diff options
author | Dave Airlie <airlied@redhat.com> | 2010-10-28 13:06:54 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-10-28 13:06:54 +1000 |
commit | bf60af579382a0d48f7a65a4cec88759cc8b683c (patch) | |
tree | c7f92a9271b6aa040bd2bbe494396916d0bf1961 | |
parent | fb22d0c06a7dc42216230e198ff443d8035e9d21 (diff) |
dri2: reference count the client privates key/callback
This lets multi-screen work better, but still having issues after server
recycle, but it doesn't crash at least.
-rw-r--r-- | src/radeon_dri2.c | 26 | ||||
-rw-r--r-- | src/radeon_probe.h | 1 |
2 files changed, 17 insertions, 10 deletions
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 1428216a..f2ea0bb4 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -1009,6 +1009,7 @@ Bool radeon_dri2_screen_init(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); DRI2InfoRec dri2_info = { 0 }; #ifdef USE_DRI2_SCHEDULING @@ -1057,19 +1058,22 @@ radeon_dri2_screen_init(ScreenPtr pScreen) xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "You need a newer kernel for sync extension\n"); } + if (pRADEONEnt->dri2_info_cnt == 0) { #if HAS_DIXREGISTERPRIVATEKEY - if (!dixRegisterPrivateKey(DRI2ClientEventsPrivateKey, PRIVATE_CLIENT, sizeof(DRI2ClientEventsRec))) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DRI2 registering private key to client failed\n"); - return FALSE; - } + if (!dixRegisterPrivateKey(DRI2ClientEventsPrivateKey, PRIVATE_CLIENT, sizeof(DRI2ClientEventsRec))) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DRI2 registering private key to client failed\n"); + return FALSE; + } #else - if (!dixRequestPrivate(DRI2ClientEventsPrivateKey, sizeof(DRI2ClientEventsRec))) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DRI2 requesting private key to client failed\n"); - return FALSE; - } + if (!dixRequestPrivate(DRI2ClientEventsPrivateKey, sizeof(DRI2ClientEventsRec))) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DRI2 requesting private key to client failed\n"); + return FALSE; + } #endif - AddCallback(&ClientStateCallback, radeon_dri2_client_state_changed, 0); + AddCallback(&ClientStateCallback, radeon_dri2_client_state_changed, 0); + } + pRADEONEnt->dri2_info_cnt++; #endif info->dri2.enabled = DRI2ScreenInit(pScreen, &dri2_info); @@ -1080,9 +1084,11 @@ void radeon_dri2_close_screen(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); #ifdef USE_DRI2_SCHEDULING - DeleteCallback(&ClientStateCallback, radeon_dri2_client_state_changed, 0); + if (--pRADEONEnt->dri2_info_cnt == 0) + DeleteCallback(&ClientStateCallback, radeon_dri2_client_state_changed, 0); #endif DRI2CloseScreen(pScreen); drmFree(info->dri2.device_name); diff --git a/src/radeon_probe.h b/src/radeon_probe.h index dc19cce8..ce3b4e62 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -649,6 +649,7 @@ typedef struct int FB_cnt; /* Map of FB region refcount */ int fd; /* for sharing across zaphod heads */ Bool fd_wakeup_registered; /* fd has already been registered for wakeup handling */ + int dri2_info_cnt; } RADEONEntRec, *RADEONEntPtr; /* radeon_probe.c */ |