summaryrefslogtreecommitdiff
path: root/src/gralloc/gralloc_kms.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gralloc/gralloc_kms.c')
-rw-r--r--src/gralloc/gralloc_kms.c38
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;