hwc: Simplify vsync code
Handle the wait properly in the kernel and remove unnecessary
thread signaling.
Change-Id: Iff05825a7a85d0353f3feb64e7f9a06cedab7869
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 7398295..c5a864e 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -233,23 +233,20 @@
{
int ret = 0;
hwc_context_t* ctx = (hwc_context_t*)(dev);
- pthread_mutex_lock(&ctx->vstate.lock);
+ Locker::Autolock _l(ctx->mBlankLock);
switch(event) {
case HWC_EVENT_VSYNC:
if (ctx->vstate.enable == enable)
break;
ret = hwc_vsync_control(ctx, dpy, enable);
- if(ret == 0) {
+ if(ret == 0)
ctx->vstate.enable = !!enable;
- pthread_cond_signal(&ctx->vstate.cond);
- }
ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
(enable)?"ENABLED":"DISABLED");
break;
default:
ret = -EINVAL;
}
- pthread_mutex_unlock(&ctx->vstate.lock);
return ret;
}
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index a310679..3fc3b3a 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -151,8 +151,6 @@
}
MDPComp::init(ctx);
- pthread_mutex_init(&(ctx->vstate.lock), NULL);
- pthread_cond_init(&(ctx->vstate.cond), NULL);
ctx->vstate.enable = false;
ctx->vstate.fakevsync = false;
ctx->mExtDispConfiguring = false;
@@ -214,8 +212,6 @@
}
- pthread_mutex_destroy(&(ctx->vstate.lock));
- pthread_cond_destroy(&(ctx->vstate.cond));
}
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 6e95703..91ad153 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -100,6 +100,11 @@
LayerProp():mFlags(0) {};
};
+struct VsyncState {
+ bool enable;
+ bool fakevsync;
+};
+
// LayerProp::flag values
enum {
HWC_MDPCOMP = 0x00000001,
@@ -228,13 +233,6 @@
}; //qhwc namespace
-struct vsync_state {
- pthread_mutex_t lock;
- pthread_cond_t cond;
- bool enable;
- bool fakevsync;
-};
-
// -----------------------------------------------------------------------------
// HWC context
// This structure contains overall state
@@ -255,6 +253,7 @@
// External display related information
qhwc::ExternalDisplay *mExtDisplay;
qhwc::MDPInfo mMDP;
+ qhwc::VsyncState vstate;
qhwc::DisplayAttributes dpyAttr[MAX_DISPLAYS];
qhwc::ListStats listStats[MAX_DISPLAYS];
qhwc::LayerProp *layerProp[MAX_DISPLAYS];
@@ -271,8 +270,6 @@
mutable Locker mBlankLock;
//Lock to protect prepare & set when detaching external disp
mutable Locker mExtLock;
- //Vsync
- struct vsync_state vstate;
//Drawing round when we use GPU
bool isPaddingRound;
};
diff --git a/libhwcomposer/hwc_vsync.cpp b/libhwcomposer/hwc_vsync.cpp
index b42043f..c0a33c1 100644
--- a/libhwcomposer/hwc_vsync.cpp
+++ b/libhwcomposer/hwc_vsync.cpp
@@ -60,7 +60,6 @@
android::PRIORITY_MORE_FAVORABLE);
const int MAX_DATA = 64;
- const int MAX_RETRY_COUNT = 100;
static char vdata[MAX_DATA];
uint64_t cur_timestamp=0;
@@ -86,6 +85,8 @@
*/
fd_timestamp = open(vsync_timestamp_fb0, O_RDONLY);
if (fd_timestamp < 0) {
+ // Make sure fb device is opened before starting this thread so this
+ // never happens.
ALOGE ("FATAL:%s:not able to open file:%s, %s", __FUNCTION__,
(fb1_vsync) ? vsync_timestamp_fb1 : vsync_timestamp_fb0,
strerror(errno));
@@ -93,46 +94,27 @@
}
do {
- pthread_mutex_lock(&ctx->vstate.lock);
- while (ctx->vstate.enable == false) {
- pthread_cond_wait(&ctx->vstate.cond, &ctx->vstate.lock);
- }
- pthread_mutex_unlock(&ctx->vstate.lock);
-
- if (!ctx->vstate.fakevsync) {
- for(int i = 0; i < MAX_RETRY_COUNT; i++) {
- len = pread(fd_timestamp, vdata, MAX_DATA, 0);
- if(len < 0 && (errno == EAGAIN ||
- errno == EINTR ||
- errno == EBUSY)) {
- ALOGW("%s: vsync read: %s, retry (%d/%d).",
- __FUNCTION__, strerror(errno), i, MAX_RETRY_COUNT);
- continue;
- } else {
- break;
- }
- }
-
+ if (LIKELY(!ctx->vstate.fakevsync)) {
+ len = pread(fd_timestamp, vdata, MAX_DATA, 0);
if (len < 0) {
- ALOGE ("FATAL:%s:not able to read file:%s, %s", __FUNCTION__,
- vsync_timestamp_fb0, strerror(errno));
- close (fd_timestamp);
- ctx->vstate.fakevsync = true;
+ // If the read was just interrupted - it is not a fatal error
+ // In either case, just continue.
+ if (errno != EAGAIN &&
+ errno != EINTR &&
+ errno != EBUSY) {
+ ALOGE ("FATAL:%s:not able to read file:%s, %s",
+ __FUNCTION__,
+ vsync_timestamp_fb0, strerror(errno));
+ }
+ continue;
}
-
// extract timestamp
const char *str = vdata;
if (!strncmp(str, "VSYNC=", strlen("VSYNC="))) {
cur_timestamp = strtoull(str + strlen("VSYNC="), NULL, 0);
- } else {
- ALOGE ("FATAL: %s: vsync timestamp not in correct format: [%s]",
- __FUNCTION__,
- str);
- ctx->vstate.fakevsync = true;
}
-
} else {
- usleep(16000);
+ usleep(16666);
cur_timestamp = systemTime();
}
// send timestamp to HAL