summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-10-28 13:06:54 +1000
committerDave Airlie <airlied@redhat.com>2010-10-28 13:06:54 +1000
commitbf60af579382a0d48f7a65a4cec88759cc8b683c (patch)
treec7f92a9271b6aa040bd2bbe494396916d0bf1961 /src
parentfb22d0c06a7dc42216230e198ff443d8035e9d21 (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.
Diffstat (limited to 'src')
-rw-r--r--src/radeon_dri2.c26
-rw-r--r--src/radeon_probe.h1
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 */