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 <martyj19@comcast.net>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Keith Packard <keithp@keithp.com>
This commit is contained in:
Chris Wilson 2010-08-18 10:21:22 +01:00
parent 19c48d3b3f
commit c882f6a22a
3 changed files with 21 additions and 4 deletions

View File

@ -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);

View File

@ -1515,19 +1515,33 @@ 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;
return TRUE;
}
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)
{

View File

@ -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);