xf86-video-modesetting: Support new vblank kernel API [v2]
drmCrtcGetSequence returns the current vblank sequence and time. drmCrtcQueueSequence queues an event for delivery at a specified vblank sequence. Use these (when available) in preference to drmWaitVBlank. v2: Remove FIRST_PIXEL_OUT_FLAG. This has been removed from the kernel API. Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
parent
627dfc2f83
commit
44d5f2eb8a
|
@ -182,6 +182,21 @@ ms_get_kernel_ust_msc(xf86CrtcPtr crtc,
|
||||||
drmVBlank vbl;
|
drmVBlank vbl;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
#ifdef DRM_IOCTL_CRTC_QUEUE_SEQUENCE
|
||||||
|
if (ms->has_queue_sequence || !ms->tried_queue_sequence) {
|
||||||
|
uint64_t ns;
|
||||||
|
ms->tried_queue_sequence = TRUE;
|
||||||
|
|
||||||
|
ret = drmCrtcGetSequence(ms->fd, drmmode_crtc->mode_crtc->crtc_id,
|
||||||
|
msc, &ns);
|
||||||
|
if (ret != -1 || errno != ENOTTY) {
|
||||||
|
ms->has_queue_sequence = TRUE;
|
||||||
|
if (ret == 0)
|
||||||
|
*ust = ns / 1000;
|
||||||
|
return ret == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/* Get current count */
|
/* Get current count */
|
||||||
vbl.request.type = DRM_VBLANK_RELATIVE | drmmode_crtc->vblank_pipe;
|
vbl.request.type = DRM_VBLANK_RELATIVE | drmmode_crtc->vblank_pipe;
|
||||||
vbl.request.sequence = 0;
|
vbl.request.sequence = 0;
|
||||||
|
@ -211,6 +226,35 @@ ms_queue_vblank(xf86CrtcPtr crtc, ms_queue_flag flags,
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* Queue an event at the specified sequence */
|
/* Queue an event at the specified sequence */
|
||||||
|
#ifdef DRM_IOCTL_CRTC_QUEUE_SEQUENCE
|
||||||
|
if (ms->has_queue_sequence || !ms->tried_queue_sequence) {
|
||||||
|
uint32_t drm_flags = 0;
|
||||||
|
uint64_t kernel;
|
||||||
|
uint64_t kernel_queued;
|
||||||
|
|
||||||
|
ms->tried_queue_sequence = TRUE;
|
||||||
|
|
||||||
|
if (flags & MS_QUEUE_RELATIVE)
|
||||||
|
drm_flags |= DRM_CRTC_SEQUENCE_RELATIVE;
|
||||||
|
if (flags & MS_QUEUE_NEXT_ON_MISS)
|
||||||
|
drm_flags |= DRM_CRTC_SEQUENCE_NEXT_ON_MISS;
|
||||||
|
|
||||||
|
kernel = ms_crtc_msc_to_kernel_msc(crtc, msc);
|
||||||
|
ret = drmCrtcQueueSequence(ms->fd, drmmode_crtc->mode_crtc->crtc_id,
|
||||||
|
drm_flags,
|
||||||
|
kernel, &kernel_queued, seq);
|
||||||
|
if (ret == 0) {
|
||||||
|
if (msc_queued)
|
||||||
|
*msc_queued = ms_kernel_msc_to_crtc_msc(crtc, kernel_queued);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != -1 || errno != ENOTTY) {
|
||||||
|
ms->has_queue_sequence = TRUE;
|
||||||
|
goto check;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
vbl.request.type = DRM_VBLANK_EVENT | drmmode_crtc->vblank_pipe;
|
vbl.request.type = DRM_VBLANK_EVENT | drmmode_crtc->vblank_pipe;
|
||||||
if (flags & MS_QUEUE_RELATIVE)
|
if (flags & MS_QUEUE_RELATIVE)
|
||||||
vbl.request.type |= DRM_VBLANK_RELATIVE;
|
vbl.request.type |= DRM_VBLANK_RELATIVE;
|
||||||
|
@ -228,6 +272,9 @@ ms_queue_vblank(xf86CrtcPtr crtc, ms_queue_flag flags,
|
||||||
*msc_queued = ms_kernel_msc_to_crtc_msc(crtc, vbl.reply.sequence);
|
*msc_queued = ms_kernel_msc_to_crtc_msc(crtc, vbl.reply.sequence);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
#ifdef DRM_IOCTL_CRTC_QUEUE_SEQUENCE
|
||||||
|
check:
|
||||||
|
#endif
|
||||||
if (errno != EBUSY) {
|
if (errno != EBUSY) {
|
||||||
ms_drm_abort_seq(scrn, seq);
|
ms_drm_abort_seq(scrn, seq);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -446,9 +493,10 @@ ms_vblank_screen_init(ScreenPtr screen)
|
||||||
modesettingEntPtr ms_ent = ms_ent_priv(scrn);
|
modesettingEntPtr ms_ent = ms_ent_priv(scrn);
|
||||||
xorg_list_init(&ms_drm_queue);
|
xorg_list_init(&ms_drm_queue);
|
||||||
|
|
||||||
ms->event_context.version = 2;
|
ms->event_context.version = 4;
|
||||||
ms->event_context.vblank_handler = ms_drm_handler;
|
ms->event_context.vblank_handler = ms_drm_handler;
|
||||||
ms->event_context.page_flip_handler = ms_drm_handler;
|
ms->event_context.page_flip_handler = ms_drm_handler;
|
||||||
|
ms->event_context.sequence_handler = ms_drm_sequence_handler;
|
||||||
|
|
||||||
/* We need to re-register the DRM fd for the synchronisation
|
/* We need to re-register the DRM fd for the synchronisation
|
||||||
* feedback on every server generation, so perform the
|
* feedback on every server generation, so perform the
|
||||||
|
|
Loading…
Reference in New Issue