summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2009-05-27 17:40:50 -0400
committerKristian Høgsberg <krh@redhat.com>2009-05-27 17:40:50 -0400
commita470e8b0b475989c1023d32900a66a4014fff19a (patch)
treeb8a6999078d9bc77dbfd8aaa1641e83293ed1cfc
parenta6196a85cae417ef973d26693e130a0ec032b8d9 (diff)
Encapsulate the drm event structure we read from the fdkms-pageflipdri2-swapbuffers
-rw-r--r--libdrm/xf86drm.h18
-rw-r--r--libdrm/xf86drmMode.c41
-rw-r--r--shared-core/drm.h2
-rw-r--r--tests/modetest/modetest.c92
4 files changed, 108 insertions, 45 deletions
diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h
index c1d173c4..67bea37f 100644
--- a/libdrm/xf86drm.h
+++ b/libdrm/xf86drm.h
@@ -667,4 +667,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 (*page_flip_handler)(int fd,
+ unsigned int frame,
+ 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 e8015e2d..f601a007 100644
--- a/libdrm/xf86drmMode.c
+++ b/libdrm/xf86drmMode.c
@@ -676,3 +676,44 @@ int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id, void *user_data)
return drmIoctl(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip);
}
+
+int drmHandleEvent(int fd, drmEventContextPtr evctx)
+{
+ char buffer[1024];
+ int len, i;
+ struct drm_event *e;
+ struct drm_event_page_flip *page_flip;
+
+ /* 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_MODE_PAGE_FLIP:
+ if (evctx->version < 1 ||
+ evctx->page_flip_handler == NULL)
+ break;
+ page_flip = (struct drm_event_page_flip *) e;
+ evctx->page_flip_handler(fd,
+ page_flip->frame,
+ page_flip->tv_sec,
+ page_flip->tv_usec,
+ U642VOID (page_flip->user_data));
+ break;
+
+ default:
+ break;
+ }
+ i += e->length;
+ }
+
+ return 0;
+}
diff --git a/shared-core/drm.h b/shared-core/drm.h
index 3b4b242e..8b504cb8 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -1140,13 +1140,13 @@ struct drm_gem_open {
struct drm_event {
uint32_t type;
uint32_t length;
- uint64_t user_data;
};
#define DRM_EVENT_MODE_PAGE_FLIP 0x01
struct drm_event_page_flip {
struct drm_event base;
+ uint64_t user_data;
uint32_t tv_sec;
uint32_t tv_usec;
uint32_t frame;
diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
index 6eed564e..a73dab1d 100644
--- a/tests/modetest/modetest.c
+++ b/tests/modetest/modetest.c
@@ -272,8 +272,9 @@ struct connector {
drmModeModeInfo *mode;
drmModeEncoder *encoder;
int crtc;
- unsigned int fb_id;
+ unsigned int fb_id[2], current_fb_id;
struct timeval start;
+
int swap_count;
};
@@ -462,8 +463,8 @@ create_test_buffer(drm_intel_bufmgr *bufmgr,
#endif
static int
-create_black_buffer(drm_intel_bufmgr *bufmgr,
- int width, int height, int *stride_out, drm_intel_bo **bo_out)
+create_grey_buffer(drm_intel_bufmgr *bufmgr,
+ int width, int height, int *stride_out, drm_intel_bo **bo_out)
{
drm_intel_bo *bo;
unsigned int *fb_ptr;
@@ -488,7 +489,7 @@ create_black_buffer(drm_intel_bufmgr *bufmgr,
return -1;
}
- memset(bo->virtual, 0, size);
+ memset(bo->virtual, 0x77, size);
drm_intel_gem_bo_unmap_gtt(bo);
*bo_out = bo;
@@ -497,6 +498,39 @@ create_black_buffer(drm_intel_bufmgr *bufmgr,
return 0;
}
+void
+page_flip_handler(int fd, unsigned int frame,
+ unsigned int sec, unsigned int usec, void *data)
+{
+ struct connector *c;
+ unsigned int new_fb_id;
+ int len, ms;
+ struct drm_event_page_flip event;
+ struct timeval end;
+ double t;
+
+ fprintf(stderr, "flip done, frame %d, time %d.%03d\n",
+ frame, sec % 100, usec / 1000);
+
+ c = data;
+ if (c->current_fb_id == c->fb_id[0])
+ new_fb_id = c->fb_id[1];
+ else
+ new_fb_id = c->fb_id[0];
+
+ drmModePageFlip(fd, c->crtc, new_fb_id, c);
+ c->current_fb_id = new_fb_id;
+ c->swap_count++;
+ if (c->swap_count == 60) {
+ gettimeofday(&end, NULL);
+ t = end.tv_sec + end.tv_usec * 1e-6 -
+ (c->start.tv_sec + c->start.tv_usec * 1e-6);
+ fprintf(stderr, "freq: %.02fHz\n", c->swap_count / t);
+ c->swap_count = 0;
+ c->start = end;
+ }
+}
+
static void
set_mode(struct connector *c, int count, int page_flip)
{
@@ -507,6 +541,7 @@ set_mode(struct connector *c, int count, int page_flip)
drm_intel_bo *bo, *other_bo;
unsigned int fb_id, other_fb_id;
int i, j, ret, width, height, x, stride;
+ drmEventContext evctx;
width = 0;
height = 0;
@@ -546,7 +581,6 @@ set_mode(struct connector *c, int count, int page_flip)
ret = drmModeSetCrtc(fd, c[i].crtc, fb_id, x, 0,
&c[i].id, 1, c[i].mode);
x += c[i].mode->hdisplay;
- c[i].fb_id = fb_id;
if (ret) {
fprintf(stderr, "failed to set mode: %s\n", strerror(errno));
@@ -557,7 +591,7 @@ set_mode(struct connector *c, int count, int page_flip)
if (!page_flip)
return;
- if (create_black_buffer(bufmgr, width, height, &stride, &other_bo))
+ if (create_grey_buffer(bufmgr, width, height, &stride, &other_bo))
return;
ret = drmModeAddFB(fd, width, height, 32, 32, stride, other_bo->handle,
@@ -574,13 +608,16 @@ set_mode(struct connector *c, int count, int page_flip)
drmModePageFlip(fd, c[i].crtc, other_fb_id, &c[i]);
gettimeofday(&c[i].start, NULL);
c[i].swap_count = 0;
+ c[i].fb_id[0] = fb_id;
+ c[i].fb_id[1] = other_fb_id;
+ c[i].current_fb_id = fb_id;
}
+ memset(&evctx, 0, sizeof evctx);
+ evctx.version = DRM_EVENT_CONTEXT_VERSION;
+ evctx.page_flip_handler = page_flip_handler;
+
while (1) {
- struct connector *c;
- unsigned int new_fb_id;
- int len, ms;
- struct drm_event_page_flip event;
struct pollfd pfd[2];
pfd[0].fd = 0;
@@ -596,40 +633,7 @@ set_mode(struct connector *c, int count, int page_flip)
if (pfd[0].revents)
break;
- len = read(fd, &event, sizeof event);
-
- if (len < sizeof event)
- break;
- if (event.base.type != DRM_EVENT_MODE_PAGE_FLIP) {
- fprintf(stderr,
- "got unhandled event %d\n", event.base.type);
- continue;
- }
-
- fprintf(stderr, "flip done, frame %d, time %d.%03d\n",
- event.frame, event.tv_sec % 100,
- event.tv_usec / 1000);
-
- c = (struct connector *) (long) event.base.user_data;
- if (c->fb_id == fb_id)
- new_fb_id = other_fb_id;
- else
- new_fb_id = fb_id;
-
- drmModePageFlip(fd, c->crtc, new_fb_id, c);
- c->fb_id = new_fb_id;
- c->swap_count++;
- if (c->swap_count == 60) {
- struct timeval end;
- double t;
-
- gettimeofday(&end, NULL);
- t = end.tv_sec + end.tv_usec * 1e-6 -
- (c->start.tv_sec + c->start.tv_usec * 1e-6);
- fprintf(stderr, "freq: %.02fHz\n", c->swap_count / t);
- c->swap_count = 0;
- c->start = end;
- }
+ drmHandleEvent(fd, &evctx);
}
}