diff options
author | Francisco Jerez <currojerez@riseup.net> | 2010-10-21 22:41:24 +0200 |
---|---|---|
committer | Francisco Jerez <currojerez@riseup.net> | 2010-10-21 22:41:24 +0200 |
commit | 258e483d47f0f63155be18981c1118261f7675a8 (patch) | |
tree | c47a4426682eb71abfc47a58862d0a2422b61421 | |
parent | 4f42708c26fa57bac7854701a6e757958c8d0654 (diff) | |
download | xorg-driver-xf86-video-nouveau-258e483d47f0f63155be18981c1118261f7675a8.tar.gz |
kms: Register a wakeup handler to poll vblank/pageflip/udev events.
Signed-off-by: Francisco Jerez <currojerez@riseup.net>
-rw-r--r-- | src/drmmode_display.c | 79 | ||||
-rw-r--r-- | src/nv_driver.c | 5 | ||||
-rw-r--r-- | src/nv_proto.h | 4 |
3 files changed, 65 insertions, 23 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 0f82543..6c0e910 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -47,9 +47,9 @@ typedef struct { uint32_t fb_id; drmModeResPtr mode_res; int cpp; + drmEventContext event_context; #ifdef HAVE_LIBUDEV struct udev_monitor *uevent_monitor; - InputHandlerProc uevent_handler; #endif } drmmode_rec, *drmmode_ptr; @@ -85,6 +85,19 @@ typedef struct { static void drmmode_output_dpms(xf86OutputPtr output, int mode); +static drmmode_ptr +drmmode_from_scrn(ScrnInfoPtr scrn) +{ + if (scrn) { + xf86CrtcConfigPtr conf = XF86_CRTC_CONFIG_PTR(scrn); + drmmode_crtc_private_ptr crtc = conf->crtc[0]->driver_private; + + return crtc->drmmode; + } + + return NULL; +} + static PixmapPtr drmmode_pixmap_wrap(ScreenPtr pScreen, int width, int height, int depth, int bpp, int pitch, struct nouveau_bo *bo, void *data) @@ -1187,20 +1200,11 @@ drmmode_cursor_init(ScreenPtr pScreen) } #ifdef HAVE_LIBUDEV -static drmmode_ptr -drmmode_from_scrn(ScrnInfoPtr scrn) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - drmmode_crtc_private_ptr drmmode_crtc; - drmmode_crtc = xf86_config->crtc[0]->driver_private; - return drmmode_crtc->drmmode; -} static void -drmmode_handle_uevents(int fd, void *closure) +drmmode_handle_uevents(ScrnInfoPtr scrn) { - ScrnInfoPtr scrn = closure; drmmode_ptr drmmode = drmmode_from_scrn(scrn); struct udev_device *dev; @@ -1213,7 +1217,7 @@ drmmode_handle_uevents(int fd, void *closure) } #endif -void +static void drmmode_uevent_init(ScrnInfoPtr scrn) { #ifdef HAVE_LIBUDEV @@ -1239,26 +1243,63 @@ drmmode_uevent_init(ScrnInfoPtr scrn) return; } - drmmode->uevent_handler = - xf86AddGeneralHandler(udev_monitor_get_fd(mon), - drmmode_handle_uevents, scrn); - + AddGeneralSocket(udev_monitor_get_fd(mon)); drmmode->uevent_monitor = mon; #endif } -void +static void drmmode_uevent_fini(ScrnInfoPtr scrn) { #ifdef HAVE_LIBUDEV drmmode_ptr drmmode = drmmode_from_scrn(scrn); - if (drmmode->uevent_handler) { + if (drmmode->uevent_monitor) { struct udev *u = udev_monitor_get_udev(drmmode->uevent_monitor); - xf86RemoveGeneralHandler(drmmode->uevent_handler); udev_monitor_unref(drmmode->uevent_monitor); udev_unref(u); } #endif } + +static void +drmmode_wakeup_handler(pointer data, int err, pointer p) +{ + ScrnInfoPtr scrn = data; + drmmode_ptr drmmode = drmmode_from_scrn(scrn); + fd_set *read_mask = p; + + if (scrn == NULL || err < 0) + return; + + if (FD_ISSET(drmmode->fd, read_mask)) + drmHandleEvent(drmmode->fd, &drmmode->event_context); + +#ifdef HAVE_LIBUDEV + if (FD_ISSET(udev_monitor_get_fd(drmmode->uevent_monitor), read_mask)) + drmmode_handle_uevents(scrn); +#endif +} + +void +drmmode_screen_init(ScreenPtr pScreen) +{ + ScrnInfoPtr scrn = xf86Screens[pScreen->myNum]; + drmmode_ptr drmmode = drmmode_from_scrn(scrn); + + drmmode_uevent_init(scrn); + AddGeneralSocket(drmmode->fd); + + /* Register a wakeup handler to get informed on DRM events */ + RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, + drmmode_wakeup_handler, scrn); +} + +void +drmmode_screen_fini(ScreenPtr pScreen) +{ + ScrnInfoPtr scrn = xf86Screens[pScreen->myNum]; + + drmmode_uevent_fini(scrn); +} diff --git a/src/nv_driver.c b/src/nv_driver.c index 094067d..cd8c001 100644 --- a/src/nv_driver.c +++ b/src/nv_driver.c @@ -423,7 +423,7 @@ NVCloseScreen(int scrnIndex, ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; NVPtr pNv = NVPTR(pScrn); - drmmode_uevent_fini(pScrn); + drmmode_screen_fini(pScreen); if (!pNv->NoAccel) nouveau_dri2_fini(pScreen); @@ -1193,7 +1193,8 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); - drmmode_uevent_init(pScrn); + drmmode_screen_init(pScreen); + return TRUE; } diff --git a/src/nv_proto.h b/src/nv_proto.h index d6791ef..7c836b2 100644 --- a/src/nv_proto.h +++ b/src/nv_proto.h @@ -7,8 +7,8 @@ void drmmode_adjust_frame(ScrnInfoPtr pScrn, int x, int y, int flags); void drmmode_remove_fb(ScrnInfoPtr pScrn); Bool drmmode_cursor_init(ScreenPtr pScreen); void drmmode_fbcon_copy(ScreenPtr pScreen); -void drmmode_uevent_init(ScrnInfoPtr); -void drmmode_uevent_fini(ScrnInfoPtr); +void drmmode_screen_init(ScreenPtr pScreen); +void drmmode_screen_fini(ScreenPtr pScreen); /* in nv_accel_common.c */ Bool NVAccelCommonInit(ScrnInfoPtr pScrn); |