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