From c882f6a22a862c1664c375e05e5e6fc4bdb04edb Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 18 Aug 2010 10:21:22 +0100 Subject: [PATCH] Move registration of vsync fd from pre-init to screen-init Marty Jack reported an issue he found where the page-flipping handler was being lost on server reset. This results in the swap completion notification being lost, with the sporadic hang of full screen applications like Compiz, flash and even glxgears! Fixes: Bug 29584 - Server in compute loop https://bugs.freedesktop.org/show_bug.cgi?id=29584 There are also several possibly related bugs with similar symptoms, i.e. OpenGL applications hanging on missed swap notifications. Reported-by: Marty Jack Signed-off-by: Chris Wilson Cc: Keith Packard --- src/intel.h | 1 + src/intel_display.c | 22 ++++++++++++++++++---- src/intel_driver.c | 2 ++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/intel.h b/src/intel.h index 970e519..ba23ac1 100644 --- a/src/intel.h +++ b/src/intel.h @@ -439,6 +439,7 @@ enum { }; extern Bool intel_mode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp); +extern void intel_mode_init(struct intel_screen_private *intel); extern void intel_mode_remove_fb(intel_screen_private *intel); extern void intel_mode_fini(intel_screen_private *intel); diff --git a/src/intel_display.c b/src/intel_display.c index 6e7ec2a..3676d99 100644 --- a/src/intel_display.c +++ b/src/intel_display.c @@ -1515,13 +1515,10 @@ Bool intel_mode_pre_init(ScrnInfoPtr scrn, int fd, int cpp) xf86DrvMsg(scrn->scrnIndex, X_INFO, "Kernel page flipping support detected, enabling\n"); intel->use_pageflipping = TRUE; - mode->flip_count = 0; + mode->event_context.version = DRM_EVENT_CONTEXT_VERSION; mode->event_context.vblank_handler = intel_vblank_handler; mode->event_context.page_flip_handler = intel_page_flip_handler; - AddGeneralSocket(fd); - RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, - drm_wakeup_handler, mode); } intel->modes = mode; @@ -1529,6 +1526,23 @@ Bool intel_mode_pre_init(ScrnInfoPtr scrn, int fd, int cpp) } void +intel_mode_init(struct intel_screen_private *intel) +{ + if (intel->use_pageflipping) { + struct intel_mode *mode = intel->modes; + + /* We need to re-register the mode->fd for the synchronisation + * feedback on every server generation, so perform the + * registration within ScreenInit and not PreInit. + */ + mode->flip_count = 0; + AddGeneralSocket(mode->fd); + RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, + drm_wakeup_handler, mode); + } +} + +void intel_mode_remove_fb(intel_screen_private *intel) { struct intel_mode *mode = intel->modes; diff --git a/src/intel_driver.c b/src/intel_driver.c index 1ef16ed..23df87b 100644 --- a/src/intel_driver.c +++ b/src/intel_driver.c @@ -1019,6 +1019,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr screen, int argc, char **argv) if (serverGeneration == 1) xf86ShowUnusedOptions(scrn->scrnIndex, scrn->options); + intel_mode_init(intel); + intel->suspended = FALSE; return uxa_resources_init(screen); -- 1.7.1