From: Keith Packard <keithp@xxxxxxxxxx> These provide a crtc-id based interface to get the current sequence (frame) number and to queue an event to be delivered at a specific sequence. Signed-off-by: Keith Packard <keithp@xxxxxxxxxx> --- include/drm/drm.h | 32 ++++++++++++++++++++++++++++++++ xf86drm.c | 33 +++++++++++++++++++++++++++++++++ xf86drm.h | 11 ++++++++++- xf86drmMode.c | 9 +++++++++ 4 files changed, 84 insertions(+), 1 deletion(-) diff --git a/include/drm/drm.h b/include/drm/drm.h index 7c736765..076040d4 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -712,6 +712,27 @@ struct drm_syncobj_handle { __u32 pad; }; +/* Query current scanout sequence number */ +struct drm_crtc_get_sequence { + __u32 crtc_id; + __u32 active; + __u64 sequence; + __s64 sequence_ns; +}; + +/* Queue event to be delivered at specified sequence */ + +#define DRM_CRTC_SEQUENCE_RELATIVE 0x00000001 /* sequence is relative to current */ +#define DRM_CRTC_SEQUENCE_NEXT_ON_MISS 0x00000002 /* Use next sequence if we've missed */ +#define DRM_CRTC_SEQUENCE_FIRST_PIXEL_OUT 0x00000004 /* Signal when first pixel is displayed */ + +struct drm_crtc_queue_sequence { + __u32 crtc_id; + __u32 flags; + __u64 sequence; /* on input, target sequence. on output, actual sequence */ + __u64 user_data; /* user data passed to event */ +}; + #if defined(__cplusplus) } #endif @@ -794,6 +815,9 @@ extern "C" { #define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank) +#define DRM_IOCTL_CRTC_GET_SEQUENCE DRM_IOWR(0x3b, struct drm_crtc_get_sequence) +#define DRM_IOCTL_CRTC_QUEUE_SEQUENCE DRM_IOWR(0x3c, struct drm_crtc_queue_sequence) + #define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw) #define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res) @@ -869,6 +893,7 @@ struct drm_event { #define DRM_EVENT_VBLANK 0x01 #define DRM_EVENT_FLIP_COMPLETE 0x02 +#define DRM_EVENT_CRTC_SEQUENCE 0x03 struct drm_event_vblank { struct drm_event base; @@ -879,6 +904,13 @@ struct drm_event_vblank { __u32 crtc_id; /* 0 on older kernels that do not support this */ }; +struct drm_event_crtc_sequence { + struct drm_event base; + __u64 user_data; + __s64 time_ns; + __u64 sequence; +}; + /* typedef area */ typedef struct drm_clip_rect drm_clip_rect_t; typedef struct drm_drawable_info drm_drawable_info_t; diff --git a/xf86drm.c b/xf86drm.c index 6ea01129..bffcd7e5 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -1695,6 +1695,39 @@ int drmUpdateDrawableInfo(int fd, drm_drawable_t handle, return 0; } +int drmCrtcGetSequence(int fd, uint32_t crtcId, uint64_t *sequence, uint64_t *ns) +{ + struct drm_crtc_get_sequence get_seq; + int ret; + + memclear(get_seq); + get_seq.crtc_id = crtcId; + ret = drmIoctl(fd, DRM_IOCTL_CRTC_GET_SEQUENCE, &get_seq); + if (ret) + return ret; + + if (sequence) + *sequence = get_seq.sequence; + if (ns) + *ns = get_seq.sequence_ns; + return 0; +} + +int drmCrtcQueueSequence(int fd, uint32_t crtcId, uint32_t flags, uint64_t sequence, uint64_t user_data) +{ + struct drm_crtc_queue_sequence queue_seq; + int ret; + + memclear(queue_seq); + queue_seq.crtc_id = crtcId; + queue_seq.flags = flags; + queue_seq.sequence = sequence; + queue_seq.user_data = user_data; + + ret = drmIoctl(fd, DRM_IOCTL_CRTC_QUEUE_SEQUENCE, &queue_seq); + return ret; +} + /** * Acquire the AGP device. * diff --git a/xf86drm.h b/xf86drm.h index 2855a3ee..ed1cacda 100644 --- a/xf86drm.h +++ b/xf86drm.h @@ -636,6 +636,11 @@ extern int drmCtlUninstHandler(int fd); extern int drmSetClientCap(int fd, uint64_t capability, uint64_t value); +extern int drmCrtcGetSequence(int fd, uint32_t crtcId, + uint64_t *sequence, uint64_t *ns); +extern int drmCrtcQueueSequence(int fd, uint32_t crtcId, + uint32_t flags, uint64_t sequence, + uint64_t user_data); /* General user-level programmer's API: authenticated client and/or X */ extern int drmMap(int fd, drm_handle_t handle, @@ -728,7 +733,7 @@ extern void drmMsg(const char *format, ...) DRM_PRINTFLIKE(1, 2); extern int drmSetMaster(int fd); extern int drmDropMaster(int fd); -#define DRM_EVENT_CONTEXT_VERSION 3 +#define DRM_EVENT_CONTEXT_VERSION 4 typedef struct _drmEventContext { @@ -755,6 +760,10 @@ typedef struct _drmEventContext { unsigned int crtc_id, void *user_data); + void (*sequence_handler)(int fd, + uint64_t sequence, + uint64_t ns, + uint64_t user_data); } drmEventContext, *drmEventContextPtr; extern int drmHandleEvent(int fd, drmEventContextPtr evctx); diff --git a/xf86drmMode.c b/xf86drmMode.c index affd3fb7..0780198e 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -889,6 +889,7 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx) int len, i; struct drm_event *e; struct drm_event_vblank *vblank; + struct drm_event_crtc_sequence *seq; void *user_data; /* The DRM read semantics guarantees that we always get only @@ -933,6 +934,14 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx) vblank->tv_usec, user_data); break; + case DRM_EVENT_CRTC_SEQUENCE: + seq = (struct drm_event_crtc_sequence *) e; + if (evctx->version >= 4 && evctx->sequence_handler) + evctx->sequence_handler(fd, + seq->sequence, + seq->time_ns, + seq->user_data); + break; default: break; } -- 2.11.0 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel