diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-09-16 19:23:24 -0700 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-09-16 19:28:40 -0700 |
commit | f8aa7b7612f4cf661469bfbf994728fb275fe9e0 (patch) | |
tree | a62b13398cb392ea9a9674fb0218a6b4e1989f73 | |
parent | 262220b8dedce190f189c42dec9696dd04e33b66 (diff) | |
parent | a470e8b0b475989c1023d32900a66a4014fff19a (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.h | 5 | ||||
-rw-r--r-- | libdrm/xf86drmMode.c | 16 | ||||
-rw-r--r-- | shared-core/drm.h | 4 | ||||
-rw-r--r-- | tests/modetest/modetest.c | 67 |
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); } } |