hwc: Add support for faking vsync
Can be set for debugging, valgrind, board bringup etc.
Also - we fail reading the sysfs vsync, we fall back and fake it.
Bug: 7301591
Change-Id: I9509fd7aa8862d5af7d521e29fe32bef9654168c
Signed-off-by: Iliyan Malchev <malchev@google.com>
Conflicts:
libhwcomposer/hwc_vsync.cpp
diff --git a/libhwcomposer/hwc_vsync.cpp b/libhwcomposer/hwc_vsync.cpp
index a3becfa..ee6af28 100644
--- a/libhwcomposer/hwc_vsync.cpp
+++ b/libhwcomposer/hwc_vsync.cpp
@@ -21,6 +21,7 @@
// WARNING : Excessive logging, if VSYNC_DEBUG enabled
#define VSYNC_DEBUG 0
+#include <cutils/properties.h>
#include <utils/Log.h>
#include <fcntl.h>
#include <sys/ioctl.h>
@@ -59,16 +60,23 @@
int ret = 0;
bool fb1_vsync = false;
bool enabled = false;
+ bool fakevsync = false;
+
+ char property[PROPERTY_VALUE_MAX];
+ if(property_get("debug.hwc.fakevsync", property, NULL) > 0) {
+ if(atoi(property) == 1)
+ fakevsync = true;
+ }
/* Currently read vsync timestamp from drivers
e.g. VSYNC=41800875994
- */
+ */
fd_timestamp = open(vsync_timestamp_fb0, O_RDONLY);
if (fd_timestamp < 0) {
ALOGE ("FATAL:%s:not able to open file:%s, %s", __FUNCTION__,
(fb1_vsync) ? vsync_timestamp_fb1 : vsync_timestamp_fb0,
strerror(errno));
- return NULL;
+ fakevsync = true;
}
do {
@@ -76,7 +84,8 @@
while (ctx->vstate.enable == false) {
if(enabled) {
int e = 0;
- if(ioctl(ctx->dpyAttr[dpy].fd, MSMFB_OVERLAY_VSYNC_CTRL,
+ if(!fakevsync &&
+ ioctl(ctx->dpyAttr[dpy].fd, MSMFB_OVERLAY_VSYNC_CTRL,
&e) < 0) {
ALOGE("%s: vsync control failed. Dpy=%d, enabled=%d : %s",
__FUNCTION__, dpy, enabled, strerror(errno));
@@ -90,8 +99,9 @@
if (!enabled) {
int e = 1;
- if(ioctl(ctx->dpyAttr[dpy].fd, MSMFB_OVERLAY_VSYNC_CTRL,
- &e) < 0) {
+ if(!fakevsync &&
+ ioctl(ctx->dpyAttr[dpy].fd, MSMFB_OVERLAY_VSYNC_CTRL,
+ &e) < 0) {
ALOGE("%s: vsync control failed. Dpy=%d, enabled=%d : %s",
__FUNCTION__, dpy, enabled, strerror(errno));
ret = -errno;
@@ -99,37 +109,44 @@
enabled = true;
}
- for(int i = 0; i < MAX_RETRY_COUNT; i++) {
- len = pread(fd_timestamp, vdata, MAX_DATA, 0);
- if(len < 0 && (errno == EAGAIN || errno == EINTR)) {
- ALOGW("%s: vsync read: EAGAIN, retry (%d/%d).",
- __FUNCTION__, i, MAX_RETRY_COUNT);
- continue;
- } else {
- break;
- }
- }
+ if(!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)) {
+ ALOGW("%s: vsync read: EAGAIN, retry (%d/%d).",
+ __FUNCTION__, i, MAX_RETRY_COUNT);
+ continue;
+ } else {
+ break;
+ }
+ }
- if (len < 0) {
- ALOGE ("FATAL:%s:not able to read file:%s, %s", __FUNCTION__,
- vsync_timestamp_fb0, strerror(errno));
- //XXX: Need to continue here since SF needs vsync signal to compose
- continue;
- }
+ if (len < 0) {
+ ALOGE ("FATAL:%s:not able to read file:%s, %s", __FUNCTION__,
+ vsync_timestamp_fb0, strerror(errno));
+ close (fd_timestamp);
+ fakevsync = true;
+ }
- // 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);
- }
- // send timestamp to HAL
- ALOGD_IF (VSYNC_DEBUG, "%s: timestamp %llu sent to HWC for %s",
- __FUNCTION__, cur_timestamp, "fb0");
- ctx->proc->vsync(ctx->proc, dpy, cur_timestamp);
+ // 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);
+ fakevsync = true;
+ }
+
+ } else {
+ usleep(16000);
+ cur_timestamp = systemTime();
+ }
+ // send timestamp to HAL
+ ALOGD_IF (VSYNC_DEBUG, "%s: timestamp %llu sent to HWC for %s",
+ __FUNCTION__, cur_timestamp, "fb0");
+ ctx->proc->vsync(ctx->proc, dpy, cur_timestamp);
} while (true);
if(fd_timestamp >= 0)
@@ -146,7 +163,7 @@
ret = pthread_create(&vsync_thread, NULL, vsync_loop, (void*) ctx);
if (ret) {
ALOGE("%s: failed to create %s: %s", __FUNCTION__,
- HWC_VSYNC_THREAD_NAME, strerror(ret));
+ HWC_VSYNC_THREAD_NAME, strerror(ret));
}
}