From c356c1c20540047359611ee544300bb903c2fe97 Mon Sep 17 00:00:00 2001 From: Neti Ravi Kumar Date: Sun, 16 Sep 2012 01:35:41 +0530 Subject: [PATCH] hwcomposer : Synchronize EventThread, and hwcVsyncThread Synchronization is needed,to make sure, read() is not called by hwcVsyncThread when VSYNC is disabled. Otherwise in usecases, where display is OFF, and still some tasks keep running in the background; SurfaceFlinger hogs CPU. (cherry picked from commit ffa84468bbd2517ffb22ab4023cb57a6272fc80d) Change-Id: Idd779647a27ed3e6fb0703a07033dd5f7cd1b5fd --- libhwcomposer/hwc.cpp | 34 +++++++++++++++++++++++++++++++--- libhwcomposer/hwc_utils.cpp | 6 ++++++ libhwcomposer/hwc_utils.h | 9 +++++++++ libhwcomposer/hwc_vsync.cpp | 14 ++++++++++---- 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp index 2b34be7..205e5e7 100644 --- a/libhwcomposer/hwc.cpp +++ b/libhwcomposer/hwc.cpp @@ -36,6 +36,7 @@ #include "hwc_extonly.h" #include "qcom_ui.h" +#define VSYNC_DEBUG 0 using namespace qhwc; static int hwc_device_open(const struct hw_module_t* module, @@ -130,19 +131,46 @@ static int hwc_eventControl(struct hwc_composer_device* dev, int event, int value) { int ret = 0; + static int prev_value, temp; + hwc_context_t* ctx = (hwc_context_t*)(dev); private_module_t* m = reinterpret_cast( ctx->mFbDev->common.module); switch(event) { #ifndef NO_HW_VSYNC case HWC_EVENT_VSYNC: + if (value == prev_value){ + //TODO see why HWC gets repeated events + ALOGD_IF(VSYNC_DEBUG, "%s - VSYNC is already %s", + __FUNCTION__, (value)?"ENABLED":"DISABLED"); + } + temp = ctx->vstate.enable; if(ioctl(m->framebuffer->fd, MSMFB_OVERLAY_VSYNC_CTRL, &value) < 0) ret = -errno; - if(ctx->mExtDisplay->isHDMIConfigured() && - (ctx->mExtDisplay->getExternalDisplay()==EXTERN_DISPLAY_FB1)) { - ret = ctx->mExtDisplay->enableHDMIVsync(value); + /* vsync state change logic */ + if (value == 1) { + //unblock vsync thread + pthread_mutex_lock(&ctx->vstate.lock); + ctx->vstate.enable = true; + pthread_cond_signal(&ctx->vstate.cond); + pthread_mutex_unlock(&ctx->vstate.lock); } + if (value == 0 && temp) { + //vsync thread will block + pthread_mutex_lock(&ctx->vstate.lock); + ctx->vstate.enable = false; + pthread_mutex_unlock(&ctx->vstate.lock); + } + ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed from %s to %s", + (prev_value)?"ENABLED":"DISABLED", (value)?"ENABLED":"DISABLED"); + prev_value = value; + /* vsync state change logic - end*/ + + if(ctx->mExtDisplay->isHDMIConfigured() && + (ctx->mExtDisplay->getExternalDisplay()==EXTERN_DISPLAY_FB1)) { + ret = ctx->mExtDisplay->enableHDMIVsync(value); + } break; #endif case HWC_EVENT_ORIENTATION: diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp index c952a46..ac6e428 100644 --- a/libhwcomposer/hwc_utils.cpp +++ b/libhwcomposer/hwc_utils.cpp @@ -66,6 +66,10 @@ void initContext(hwc_context_t *ctx) property_get("debug.hwc.dynThreshold", value, "2"); ctx->dynThreshold = atof(value); + pthread_mutex_init(&(ctx->vstate.lock), NULL); + pthread_cond_init(&(ctx->vstate.cond), NULL); + ctx->vstate.enable = false; + ALOGI("Initializing Qualcomm Hardware Composer"); ALOGI("MDP version: %d", ctx->mMDP.version); ALOGI("DYN composition threshold : %f", ctx->dynThreshold); @@ -98,6 +102,8 @@ void closeContext(hwc_context_t *ctx) ctx->mExtDisplay = NULL; } + pthread_mutex_destroy(&(ctx->vstate.lock)); + pthread_cond_destroy(&(ctx->vstate.cond)); free(const_cast(ctx->device.methods)); diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h index 774810f..fa1cdf0 100644 --- a/libhwcomposer/hwc_utils.h +++ b/libhwcomposer/hwc_utils.h @@ -133,6 +133,12 @@ inline void getLayerResolution(const hwc_layer_t* layer, } }; //qhwc namespace +struct vsync_state { + pthread_mutex_t lock; + pthread_cond_t cond; + bool enable; +}; + // ----------------------------------------------------------------------------- // HWC context // This structure contains overall state @@ -164,6 +170,9 @@ struct hwc_context_t { qhwc::MDPInfo mMDP; + //Vsync + struct vsync_state vstate; + }; #endif //HWC_UTILS_H diff --git a/libhwcomposer/hwc_vsync.cpp b/libhwcomposer/hwc_vsync.cpp index 4e4eb44..cc86312 100644 --- a/libhwcomposer/hwc_vsync.cpp +++ b/libhwcomposer/hwc_vsync.cpp @@ -42,7 +42,8 @@ static void *vsync_loop(void *param) char thread_name[64] = "hwcVsyncThread"; prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0); - setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); + setpriority(PRIO_PROCESS, 0, + HAL_PRIORITY_URGENT_DISPLAY + ANDROID_PRIORITY_MORE_FAVORABLE); static char vdata[PAGE_SIZE]; @@ -51,12 +52,17 @@ static void *vsync_loop(void *param) bool fb1_vsync = false; /* Currently read vsync timestamp from drivers - VSYNC=41800875994 + e.g. VSYNC=41800875994 */ hwc_procs* proc = (hwc_procs*)ctx->device.reserved_proc[0]; do { + pthread_mutex_lock(&ctx->vstate.lock); + if(ctx->vstate.enable == false) { + pthread_cond_wait(&ctx->vstate.cond, &ctx->vstate.lock); + } + pthread_mutex_unlock(&ctx->vstate.lock); int hdmiconnected = ctx->mExtDisplay->getExternalDisplay(); @@ -78,15 +84,15 @@ static void *vsync_loop(void *param) ALOGE ("FATAL:%s:not able to open file:%s, %s", __FUNCTION__, (fb1_vsync) ? vsync_timestamp_fb1 : vsync_timestamp_fb0, strerror(errno)); - return NULL; + return NULL; } - // Open success - read now len = read(fd_timestamp, vdata, PAGE_SIZE); if (len < 0){ ALOGE ("FATAL:%s:not able to read file:%s, %s", __FUNCTION__, (fb1_vsync) ? vsync_timestamp_fb1 : vsync_timestamp_fb0, strerror(errno)); + fd_timestamp = -1; return NULL; }