diff options
Diffstat (limited to 'src/gralloc/gralloc_kms.c')
-rw-r--r-- | src/gralloc/gralloc_kms.c | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/src/gralloc/gralloc_kms.c b/src/gralloc/gralloc_kms.c index 6ae9446244..7bc65b3438 100644 --- a/src/gralloc/gralloc_kms.c +++ b/src/gralloc/gralloc_kms.c @@ -63,28 +63,52 @@ 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); - if (ret && errno == -EBUSY) { + /* 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 (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"); @@ -202,8 +226,10 @@ drm_kms_init_locked(struct drm_module_t *drm) return 0; drm->resources = drmModeGetResources(drm->fd); - if (!drm->resources) + if (!drm->resources) { + LOGE("failed to get modeset resources"); return -EINVAL; + } for (i = 0; i < drm->resources->count_connectors; i++) { drmModeConnectorPtr connector; |