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