From f27a8a332173a6cc1096e6fb3d5f9fc132ed4f9f Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 28 Mar 2011 22:20:12 +0800 Subject: gralloc: improve page flip blocking Use DRM_MODE_PAGE_FLIP_EVENT. --- src/gralloc/gralloc_kms.c | 42 +++++++++++++++++++++++++++++------------- 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 -- cgit v1.2.3