summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGowtham Tammana <g-tammana@ti.com>2016-03-24 15:06:37 -0500
committerGowtham Tammana <g-tammana@ti.com>2016-05-05 14:35:12 -0500
commita0f3fe940ec8a3528ac9609c1a67f895f47defb2 (patch)
treef94cd4e6886801ac9dfcedb8051e129cf826e80f
parentd836e7d8ddab3d043abdd1c42cf98eb25c8c91d9 (diff)
downloaddra7xx-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.c20
-rw-r--r--hwcomposer/display.h4
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;