summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2009-09-16 19:23:24 -0700
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-09-16 19:28:40 -0700
commitf8aa7b7612f4cf661469bfbf994728fb275fe9e0 (patch)
treea62b13398cb392ea9a9674fb0218a6b4e1989f73
parent262220b8dedce190f189c42dec9696dd04e33b66 (diff)
parenta470e8b0b475989c1023d32900a66a4014fff19a (diff)
Merge commit 'origin/kms-pageflip' into vblank-eventvblank-event
Conflicts: libdrm/xf86drm.h shared-core/drm.h tests/modetest/modetest.c
-rw-r--r--libdrm/xf86drm.h5
-rw-r--r--libdrm/xf86drmMode.c16
-rw-r--r--shared-core/drm.h4
-rw-r--r--tests/modetest/modetest.c67
4 files changed, 74 insertions, 18 deletions
diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h
index 2cb9c9e9..c834c1b6 100644
--- a/libdrm/xf86drm.h
+++ b/libdrm/xf86drm.h
@@ -681,6 +681,11 @@ typedef struct _drmEventContext {
unsigned int tv_sec,
unsigned int tv_usec,
void *user_data);
+ void (*page_flip_handler)(int fd,
+ unsigned int frame,
+ unsigned int tv_sec,
+ unsigned int tv_usec,
+ void *user_data);
} drmEventContext, *drmEventContextPtr;
diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c
index 7d931704..a48467fb 100644
--- a/libdrm/xf86drmMode.c
+++ b/libdrm/xf86drmMode.c
@@ -672,7 +672,8 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx)
int len, i;
struct drm_event *e;
struct drm_event_vblank *vblank;
-
+ struct drm_event_page_flip *page_flip;
+
/* The DRM read semantics guarantees that we always get only
* complete events. */
@@ -697,7 +698,17 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx)
vblank->tv_usec,
U642VOID (vblank->user_data));
break;
-
+ 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;
}
@@ -718,3 +729,4 @@ int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id, void *user_data)
return drmIoctl(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip);
}
+
diff --git a/shared-core/drm.h b/shared-core/drm.h
index a76a24c2..2035841a 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -838,14 +838,14 @@ struct drm_event_vblank {
uint32_t reserved;
};
-#define DRM_EVENT_MODE_PAGE_FLIP 0x01
+#define DRM_EVENT_MODE_PAGE_FLIP 0x02
struct drm_event_page_flip {
struct drm_event base;
+ uint64_t user_data;
uint32_t tv_sec;
uint32_t tv_usec;
uint32_t frame;
- uint64_t user_data;
};
/* typedef area */
diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
index 8cddca76..66fc0d43 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)
{
@@ -505,8 +539,10 @@ set_mode(struct connector *c, int count, int page_flip)
struct drm_mode_modeinfo *mode = NULL;
drm_intel_bufmgr *bufmgr;
drm_intel_bo *bo, *other_bo;
- unsigned int fb_id, other_fb_id;
- int i, j, ret, width, height, x, stride;
+ unsigned int fb_id, other_fb_id, new_fb_id;
+ int i, j, ret, width, height, x, stride, len;
+ drmEventContext evctx;
+ struct drm_event_page_flip event;
width = 0;
height = 0;
@@ -546,7 +582,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 +592,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 +609,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;
@@ -611,13 +649,13 @@ set_mode(struct connector *c, int count, int page_flip)
event.tv_usec / 1000);
c = (struct connector *) (long) event.user_data;
- if (c->fb_id == fb_id)
+ if (c->fb_id[0] == 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->fb_id[0] = new_fb_id;
c->swap_count++;
if (c->swap_count == 60) {
struct timeval end;
@@ -630,6 +668,7 @@ set_mode(struct connector *c, int count, int page_flip)
c->swap_count = 0;
c->start = end;
}
+ drmHandleEvent(fd, &evctx);
}
}