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:
parent
673e4933a1
commit
c356c1c205
@ -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:
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user