summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2010-10-21 22:41:24 +0200
committerFrancisco Jerez <currojerez@riseup.net>2010-10-21 22:41:24 +0200
commit258e483d47f0f63155be18981c1118261f7675a8 (patch)
treec47a4426682eb71abfc47a58862d0a2422b61421
parent4f42708c26fa57bac7854701a6e757958c8d0654 (diff)
downloadxorg-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.c79
-rw-r--r--src/nv_driver.c5
-rw-r--r--src/nv_proto.h4
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);