summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChia-I Wu <olvaffe@gmail.com>2011-03-28 22:20:12 +0800
committerChia-I Wu <olvaffe@gmail.com>2011-03-28 22:20:29 +0800
commitf27a8a332173a6cc1096e6fb3d5f9fc132ed4f9f (patch)
tree75ccf88e764550570bd3a9412a4f4a2bf64d991c
parent98e1078d71315f1ce78562de621f8c77bf3941dd (diff)
gralloc: improve page flip blocking
Use DRM_MODE_PAGE_FLIP_EVENT.
-rw-r--r--src/gralloc/gralloc_kms.c42
-rw-r--r--src/gralloc/gralloc_mod.h1
2 files changed, 30 insertions, 13 deletions
diff --git a/src/gralloc/gralloc_kms.c b/src/gralloc/gralloc_kms.c
index a6b4e30..7bc65b3 100644
--- a/src/gralloc/gralloc_kms.c
+++ b/src/gralloc/gralloc_kms.c
@@ -63,39 +63,55 @@ drm_kms_set_crtc(struct drm_module_t *drm, struct drm_bo_t *bo)
return ret;
}
+static void page_flip_handler(int fd, unsigned int sequence,
+ unsigned int tv_sec, unsigned int tv_usec,
+ void *user_data)
+{
+ struct drm_module_t *drm = (struct drm_module_t *) user_data;
+
+ drm->flip_pending = 0;
+}
+
static int
drm_kms_page_flip(struct drm_module_t *drm, struct drm_bo_t *bo)
{
- int waits = 3, ret;
+ int retries = 3, ret;
if (drm->swap_interval > 1)
drm_kms_wait_vblank(drm, drm->swap_interval - 1);
- while (waits) {
- ret = drmModePageFlip(drm->fd, drm->crtc_id, bo->fb_id, 0x0, NULL);
+ /* TODO throttle page flip instead of retrying here */
+ while (retries) {
+ ret = drmModePageFlip(drm->fd, drm->crtc_id, bo->fb_id,
+ DRM_MODE_PAGE_FLIP_EVENT, (void *) drm);
if (ret && errno == EBUSY) {
if (drm->swap_interval)
drm_kms_wait_vblank(drm, 1);
else
usleep(5000);
- waits--;
+ retries--;
}
else {
+ if (!ret)
+ drm->flip_pending = 1;
break;
}
}
- if (ret) {
- LOGE("failed to perform page flip");
- }
- else if (drm->mode_page_flip_blocking) {
- /*
- * TODO page flip with DRM_MODE_PAGE_FLIP_EVENT instead of waiting for
- * next vblank
- */
- drm_kms_wait_vblank(drm, 1);
+ if (drm->mode_page_flip_blocking && drm->flip_pending) {
+ drmEventContext ctx;
+
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.version = DRM_EVENT_CONTEXT_VERSION;
+ ctx.page_flip_handler = page_flip_handler;
+
+ while (drm->flip_pending)
+ drmHandleEvent(drm->fd, &ctx);
}
+ if (ret)
+ LOGE("failed to perform page flip");
+
return ret;
}
diff --git a/src/gralloc/gralloc_mod.h b/src/gralloc/gralloc_mod.h
index 33ababc..33f6e9a 100644
--- a/src/gralloc/gralloc_mod.h
+++ b/src/gralloc/gralloc_mod.h
@@ -35,6 +35,7 @@ struct drm_module_t {
int vblank_secondary;
int first_post;
+ int flip_pending;
};
static inline int