summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2009-09-11 13:27:35 -0400
committerKristian Høgsberg <krh@redhat.com>2009-09-11 13:27:35 -0400
commit4ba680108ccd6e670ac516bfffd214251fb0eb83 (patch)
tree1c0cd1902c666c7955eff9cde373661b76180265
parent67e4172394a88d4922fb8d9c7c3d96ce7e02c5a6 (diff)
Add support for vblank event
-rw-r--r--libdrm/xf86drm.h19
-rw-r--r--libdrm/xf86drmMode.c43
-rw-r--r--shared-core/drm.h28
-rw-r--r--tests/Makefile.am3
4 files changed, 92 insertions, 1 deletions
diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h
index c1d173c44..2cb9c9e98 100644
--- a/libdrm/xf86drm.h
+++ b/libdrm/xf86drm.h
@@ -271,6 +271,7 @@ typedef struct _drmTextureRegion {
typedef enum {
DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
+ DRM_VBLANK_EVENT = 0x4000000, /**< Send event instead of blocking */
DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */
DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */
DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */
@@ -667,4 +668,22 @@ extern void drmMsg(const char *format, ...);
extern int drmSetMaster(int fd);
extern int drmDropMaster(int fd);
+#define DRM_EVENT_CONTEXT_VERSION 1
+
+typedef struct _drmEventContext {
+
+ /* This struct is versioned so we can add more pointers if we
+ * add more events. */
+ int version;
+
+ void (*vblank_handler)(int fd,
+ unsigned int sequence,
+ unsigned int tv_sec,
+ unsigned int tv_usec,
+ void *user_data);
+
+} drmEventContext, *drmEventContextPtr;
+
+extern int drmHandleEvent(int fd, drmEventContextPtr evctx);
+
#endif
diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c
index ea11207ec..5fdcfa47b 100644
--- a/libdrm/xf86drmMode.c
+++ b/libdrm/xf86drmMode.c
@@ -46,6 +46,7 @@
#include <drm.h>
#include <string.h>
#include <dirent.h>
+#include <unistd.h>
#include <errno.h>
#define U642VOID(x) ((void *)(unsigned long)(x))
@@ -664,3 +665,45 @@ int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
return 0;
}
+
+int drmHandleEvent(int fd, drmEventContextPtr evctx)
+{
+ char buffer[1024];
+ int len, i;
+ struct drm_event *e;
+ struct drm_event_vblank *vblank;
+
+ /* The DRM read semantics guarantees that we always get only
+ * complete events. */
+
+ len = read(fd, buffer, sizeof buffer);
+ if (len == 0)
+ return 0;
+ if (len < sizeof *e)
+ return -1;
+
+ i = 0;
+ while (i < len) {
+ e = (struct drm_event *) &buffer[i];
+ switch (e->type) {
+ case DRM_EVENT_VBLANK:
+ if (evctx->version < 1 ||
+ evctx->vblank_handler == NULL)
+ break;
+ vblank = (struct drm_event_vblank *) e;
+ evctx->vblank_handler(fd,
+ vblank->sequence,
+ vblank->tv_sec,
+ vblank->tv_usec,
+ U642VOID (vblank->user_data));
+ break;
+
+ default:
+ break;
+ }
+ i += e->length;
+ }
+
+ return 0;
+}
+
diff --git a/shared-core/drm.h b/shared-core/drm.h
index d97844f83..089e184a6 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -809,6 +809,34 @@ struct drm_gem_open {
#define DRM_COMMAND_BASE 0x40
#define DRM_COMMAND_END 0xA0
+/**
+ * Header for events written back to userspace on the drm fd. The
+ * type defines the type of event, the length specifies the total
+ * length of the event (including the header), and user_data is
+ * typically a 64 bit value passed with the ioctl that triggered the
+ * event. A read on the drm fd will always only return complete
+ * events, that is, if for example the read buffer is 100 bytes, and
+ * there are two 64 byte events pending, only one will be returned.
+ *
+ * Event types 0 - 0x7fffffff are generic drm events, 0x80000000 and
+ * up are chipset specific.
+ */
+struct drm_event {
+ uint32_t type;
+ uint32_t length;
+};
+
+#define DRM_EVENT_VBLANK 0x01
+
+struct drm_event_vblank {
+ struct drm_event base;
+ uint64_t user_data;
+ uint32_t tv_sec;
+ uint32_t tv_usec;
+ uint32_t sequence;
+ uint32_t reserved;
+};
+
/* typedef area */
#ifndef __KERNEL__
typedef struct drm_clip_rect drm_clip_rect_t;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 98c106b30..0c661628c 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -40,7 +40,8 @@ TESTS = \
gem_basic \
gem_flink \
gem_readwrite \
- gem_mmap
+ gem_mmap \
+ vblank
EXTRA_PROGRAMS = $(TESTS)