diff options
author | Gowtham Tammana <g-tammana@ti.com> | 2016-03-24 15:06:37 -0500 |
---|---|---|
committer | Gowtham Tammana <g-tammana@ti.com> | 2016-05-05 14:35:12 -0500 |
commit | a0f3fe940ec8a3528ac9609c1a67f895f47defb2 (patch) | |
tree | f94cd4e6886801ac9dfcedb8051e129cf826e80f | |
parent | d836e7d8ddab3d043abdd1c42cf98eb25c8c91d9 (diff) | |
download | dra7xx-a0f3fe940ec8a3528ac9609c1a67f895f47defb2.tar.gz |
hwc: maintain ping-pong through cond var
Choreographer is not bounded by vsync rate, and can render frames
at much faster rate. Throttle the display update through cond var
to avoid case of an update coming in too early.
Change-Id: I4c8c430804a493d8bd978a351526382c97370c58
Signed-off-by: Gowtham Tammana <g-tammana@ti.com>
-rw-r--r-- | hwcomposer/display.c | 20 | ||||
-rw-r--r-- | hwcomposer/display.h | 4 |
2 files changed, 24 insertions, 0 deletions
diff --git a/hwcomposer/display.c b/hwcomposer/display.c index b29c4d3..0ed70d6 100644 --- a/hwcomposer/display.c +++ b/hwcomposer/display.c @@ -558,6 +558,11 @@ static void page_flip_handler(int fd, unsigned frame, unsigned int sec, ret = display_release_drm_fd(display, &kdisp->fb_bufs.current); kdisp->fb_bufs.current = kdisp->fb_bufs.next; } + + pthread_mutex_lock(&display->lock); + display->is_flip_pending = false; + pthread_cond_signal(&display->cond_flip); + pthread_mutex_unlock(&display->lock); } /* @@ -686,6 +691,10 @@ int init_primary_display(omap_hwc_device_t *hwc_dev) display->retire_sync.signaled_fences = 0; pthread_mutex_init(&display->retire_sync.lock, NULL); + pthread_mutex_init(&display->lock, NULL); + pthread_cond_init(&display->cond_flip, NULL); + display->is_flip_pending = false; + set_primary_display_transform_matrix(hwc_dev); primary_display_t *primary = get_primary_display_info(hwc_dev); @@ -952,18 +961,25 @@ int update_display(omap_hwc_device_t *ctx, int disp, kdisp->fb_bufs.updated = false; } else { + pthread_mutex_lock(&display->lock); + while (display->is_flip_pending) { + pthread_cond_wait(&display->cond_flip, &display->lock); + } fence_fd = timeline_create_fence(&display->retire_sync, "hwc_retire_fence2", TWO_FLIP_EVENTS); ret = drmModePageFlip(ctx->drm_fd, kdisp->crtc_id, fb_info.fb_id, DRM_MODE_PAGE_FLIP_EVENT, display); if (ret) { ALOGE("cannot flip on connector %d", kdisp->crtc_id); + pthread_mutex_unlock(&display->lock); close(fence_fd); fence_fd = -1; goto fb_cleanup; } kdisp->fb_bufs.next = fb_info; kdisp->fb_bufs.updated = true; + display->is_flip_pending = true; + pthread_mutex_unlock(&display->lock); } /* we scheduled flip, assign release and retire fences, currently we make @@ -1136,6 +1152,10 @@ int add_external_hdmi_display(omap_hwc_device_t *hwc_dev) display->retire_sync.signaled_fences = 0; pthread_mutex_init(&display->retire_sync.lock, NULL); + pthread_mutex_init(&display->lock, NULL); + pthread_cond_init(&display->cond_flip, NULL); + display->is_flip_pending = false; + /* SurfaceFlinger currently doesn't unblank external display on reboot. * Unblank HDMI display by default. * See SurfaceFlinger::readyToRun() function. diff --git a/hwcomposer/display.h b/hwcomposer/display.h index d3a6a7d..b1cd407 100644 --- a/hwcomposer/display.h +++ b/hwcomposer/display.h @@ -217,6 +217,10 @@ struct display { kms_display_t disp_link; dss_platform_info_t limits; timeline_info_t retire_sync; + + pthread_mutex_t lock; + pthread_cond_t cond_flip; + bool is_flip_pending; }; typedef struct display display_t; |