diff options
-rw-r--r-- | src/drmmode_display.c | 13 | ||||
-rw-r--r-- | src/radeon_drm_queue.c | 110 | ||||
-rw-r--r-- | src/radeon_drm_queue.h | 1 | ||||
-rw-r--r-- | src/radeon_present.c | 2 |
4 files changed, 96 insertions, 30 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 73eadeb1..b4c9783c 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2587,9 +2587,8 @@ static void drm_wakeup_handler(pointer data, int err, pointer p) #endif { - ScrnInfoPtr scrn = data; - RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); - RADEONInfoPtr info = RADEONPTR(scrn); + drmmode_ptr drmmode = data; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(drmmode->scrn); #if !HAVE_NOTIFY_FD fd_set *read_mask = p; @@ -2597,7 +2596,7 @@ drm_wakeup_handler(pointer data, int err, pointer p) if (err >= 0 && FD_ISSET(pRADEONEnt->fd, read_mask)) #endif { - drmHandleEvent(pRADEONEnt->fd, &info->drmmode.event_context); + radeon_drm_handle_event(pRADEONEnt->fd, &drmmode->event_context); } } @@ -2747,11 +2746,13 @@ void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode) info->drmmode_inited = TRUE; if (pRADEONEnt->fd_wakeup_registered != serverGeneration) { #if HAVE_NOTIFY_FD - SetNotifyFd(pRADEONEnt->fd, drm_notify_fd, X_NOTIFY_READ, pScrn); + SetNotifyFd(pRADEONEnt->fd, drm_notify_fd, X_NOTIFY_READ, + &info->drmmode); #else AddGeneralSocket(pRADEONEnt->fd); RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, - drm_wakeup_handler, pScrn); + drm_wakeup_handler, + &info->drmmode); #endif pRADEONEnt->fd_wakeup_registered = serverGeneration; pRADEONEnt->fd_wakeup_ref = 1; diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c index 69474be2..3d2f4d15 100644 --- a/src/radeon_drm_queue.c +++ b/src/radeon_drm_queue.c @@ -40,6 +40,7 @@ struct radeon_drm_queue_entry { struct xorg_list list; + uint64_t usec; uint64_t id; uintptr_t seq; void *data; @@ -47,36 +48,73 @@ struct radeon_drm_queue_entry { xf86CrtcPtr crtc; radeon_drm_handler_proc handler; radeon_drm_abort_proc abort; + unsigned int frame; }; static int radeon_drm_queue_refcnt; static struct xorg_list radeon_drm_queue; +static struct xorg_list radeon_drm_flip_signalled; +static struct xorg_list radeon_drm_vblank_signalled; static uintptr_t radeon_drm_queue_seq; /* - * Handle a DRM event + * Process a DRM event */ static void -radeon_drm_queue_handler(int fd, unsigned int frame, unsigned int sec, - unsigned int usec, void *user_ptr) +radeon_drm_queue_handle_one(struct radeon_drm_queue_entry *e) { - uintptr_t seq = (uintptr_t)user_ptr; - struct radeon_drm_queue_entry *e, *tmp; - - xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) { - if (e->seq == seq) { - xorg_list_del(&e->list); - if (e->handler) - e->handler(e->crtc, frame, - (uint64_t)sec * 1000000 + usec, - e->data); - else - e->abort(e->crtc, e->data); - free(e); - break; - } + xorg_list_del(&e->list); + if (e->handler) { + e->handler(e->crtc, e->frame, e->usec, e->data); + } else + e->abort(e->crtc, e->data); + free(e); +} + +static void +radeon_drm_queue_handler(struct xorg_list *signalled, unsigned int frame, + unsigned int sec, unsigned int usec, void *user_ptr) +{ + uintptr_t seq = (uintptr_t)user_ptr; + struct radeon_drm_queue_entry *e, *tmp; + + xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) { + if (e->seq == seq) { + if (!e->handler) { + e->abort(e->crtc, e->data); + break; + } + + xorg_list_del(&e->list); + e->usec = (uint64_t)sec * 1000000 + usec; + e->frame = frame; + xorg_list_append(&e->list, signalled); + break; } + } +} + +/* + * Signal a DRM page flip event + */ +static void +radeon_drm_page_flip_handler(int fd, unsigned int frame, unsigned int sec, + unsigned int usec, void *user_ptr) +{ + radeon_drm_queue_handler(&radeon_drm_flip_signalled, frame, sec, usec, + user_ptr); +} + +/* + * Signal a DRM vblank event + */ +static void +radeon_drm_vblank_handler(int fd, unsigned int frame, unsigned int sec, + unsigned int usec, void *user_ptr) +{ + radeon_drm_queue_handler(&radeon_drm_vblank_signalled, frame, sec, usec, + user_ptr); } /* @@ -178,16 +216,40 @@ radeon_drm_abort_id(uint64_t id) } /* + * drmHandleEvent wrapper + */ +int +radeon_drm_handle_event(int fd, drmEventContext *event_context) +{ + struct radeon_drm_queue_entry *e, *tmp; + int r; + + r = drmHandleEvent(fd, event_context); + + xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_flip_signalled, list) + radeon_drm_queue_handle_one(e); + + xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_vblank_signalled, list) + radeon_drm_queue_handle_one(e); + + return r; +} + +/* * Wait for pending page flip on given CRTC to complete */ void radeon_drm_wait_pending_flip(xf86CrtcPtr crtc) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); - drmmode_ptr drmmode = drmmode_crtc->drmmode; + struct radeon_drm_queue_entry *e, *tmp; + + xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_flip_signalled, list) + radeon_drm_queue_handle_one(e); - while (drmmode_crtc->flip_pending && - drmHandleEvent(pRADEONEnt->fd, &drmmode->event_context) > 0); + while (drmmode_crtc->flip_pending + && radeon_drm_handle_event(pRADEONEnt->fd, + &drmmode_crtc->drmmode->event_context) > 0); } /* @@ -200,13 +262,15 @@ radeon_drm_queue_init(ScrnInfoPtr scrn) drmmode_ptr drmmode = &info->drmmode; drmmode->event_context.version = 2; - drmmode->event_context.vblank_handler = radeon_drm_queue_handler; - drmmode->event_context.page_flip_handler = radeon_drm_queue_handler; + drmmode->event_context.vblank_handler = radeon_drm_vblank_handler; + drmmode->event_context.page_flip_handler = radeon_drm_page_flip_handler; if (radeon_drm_queue_refcnt++) return; xorg_list_init(&radeon_drm_queue); + xorg_list_init(&radeon_drm_flip_signalled); + xorg_list_init(&radeon_drm_vblank_signalled); } /* diff --git a/src/radeon_drm_queue.h b/src/radeon_drm_queue.h index 96f88bd3..59343361 100644 --- a/src/radeon_drm_queue.h +++ b/src/radeon_drm_queue.h @@ -47,6 +47,7 @@ uintptr_t radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, void radeon_drm_abort_client(ClientPtr client); void radeon_drm_abort_entry(uintptr_t seq); void radeon_drm_abort_id(uint64_t id); +int radeon_drm_handle_event(int fd, drmEventContext *event_context); void radeon_drm_wait_pending_flip(xf86CrtcPtr crtc); void radeon_drm_queue_init(ScrnInfoPtr scrn); void radeon_drm_queue_close(ScrnInfoPtr scrn); diff --git a/src/radeon_present.c b/src/radeon_present.c index 2982d728..ffc14a0e 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -110,7 +110,7 @@ radeon_present_flush_drm_events(ScreenPtr screen) if (r <= 0) return 0; - return drmHandleEvent(pRADEONEnt->fd, &drmmode->event_context) >= 0; + return radeon_drm_handle_event(pRADEONEnt->fd, &drmmode->event_context) >= 0; } /* |