summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2017-07-01 00:43:15 -0700
committerDave Airlie <airlied@redhat.com>2017-12-18 10:04:02 +1000
commitd4331dda5b5969922c4f1e3ad6d53f23becb91ab (patch)
treef6ee7cae925d839993c7e23acc2d185fe2a9073c
parentc4171535389d72e9135c9615cecd07b346fd6d7e (diff)
drm: Add CrtcGetSequence and CrtcQueueSequence IOCTLs [v2]
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. v2: Remove FIRST_PIXEL_OUT flag. This has been removed from the proposed kernel API Signed-off-by: Keith Packard <keithp@keithp.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--xf86drm.c37
-rw-r--r--xf86drm.h12
-rw-r--r--xf86drmMode.c9
3 files changed, 57 insertions, 1 deletions
diff --git a/xf86drm.c b/xf86drm.c
index deb76e4b..74b4e230 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -1695,6 +1695,43 @@ 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 *sequence_queued, 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);
+ if (ret == 0 && sequence_queued)
+ *sequence_queued = queue_seq.sequence;
+
+ return ret;
+}
+
/**
* Acquire the AGP device.
*
diff --git a/xf86drm.h b/xf86drm.h
index 0dbf4941..7773d71a 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -636,6 +636,12 @@ 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 *sequence_queued,
+ 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 +734,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 +761,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 eddad8c4..15957ffc 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;
}