diff options
author | Chia-I Wu <olvaffe@gmail.com> | 2011-03-28 22:20:12 +0800 |
---|---|---|
committer | Chia-I Wu <olvaffe@gmail.com> | 2011-03-28 22:20:29 +0800 |
commit | f27a8a332173a6cc1096e6fb3d5f9fc132ed4f9f (patch) | |
tree | 75ccf88e764550570bd3a9412a4f4a2bf64d991c | |
parent | 98e1078d71315f1ce78562de621f8c77bf3941dd (diff) |
gralloc: improve page flip blocking
Use DRM_MODE_PAGE_FLIP_EVENT.
-rw-r--r-- | src/gralloc/gralloc_kms.c | 42 | ||||
-rw-r--r-- | src/gralloc/gralloc_mod.h | 1 |
2 files changed, 30 insertions, 13 deletions
diff --git a/src/gralloc/gralloc_kms.c b/src/gralloc/gralloc_kms.c index a6b4e30052..7bc65b3438 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 33ababcb35..33f6e9a91d 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 |