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
This commit is contained in:
Neti Ravi Kumar 2012-09-16 01:35:41 +05:30 committed by andrew.boren
parent 673e4933a1
commit c356c1c205
4 changed files with 56 additions and 7 deletions

View File

@ -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<private_module_t*>(
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:

View File

@ -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<hwc_methods_t *>(ctx->device.methods));

View File

@ -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

View File

@ -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;
}