Add support for sending VSYNC events to the framework

use gui/DisplayEvent to receive the events. Events are
dispatched through a unix pipe, so the API is compatible
with utils/Looper. see gui/DisplayEvent.h for more info.

Bug: 1475048
Change-Id: Ia720f64d1b950328b47b22c6a86042e481d35f09
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 39f0f40..d5a8d08 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -34,6 +34,8 @@
 #include <binder/MemoryHeapBase.h>
 #include <binder/PermissionCache.h>
 
+#include <gui/IDisplayEventConnection.h>
+
 #include <utils/String8.h>
 #include <utils/String16.h>
 #include <utils/StopWatch.h>
@@ -46,6 +48,8 @@
 #include <GLES/gl.h>
 
 #include "clz.h"
+#include "DisplayEventConnection.h"
+#include "EventThread.h"
 #include "GLExtensions.h"
 #include "DdmConnection.h"
 #include "Layer.h"
@@ -293,12 +297,16 @@
     // put the origin in the left-bottom corner
     glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
 
-    mReadyToRunBarrier.open();
+
+    // start the EventThread
+    mEventThread = new EventThread(this);
 
     /*
      *  We're now ready to accept clients...
      */
 
+    mReadyToRunBarrier.open();
+
     // start boot animation
     property_set("ctl.start", "bootanim");
 
@@ -319,6 +327,22 @@
     mEventQueue.invalidate();
 }
 
+status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
+        nsecs_t reltime, uint32_t flags) {
+    return mEventQueue.postMessage(msg, reltime);
+}
+
+status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
+        nsecs_t reltime, uint32_t flags) {
+    status_t res = mEventQueue.postMessage(msg, reltime);
+    if (res == NO_ERROR) {
+        msg->wait();
+    }
+    return res;
+}
+
+// ----------------------------------------------------------------------------
+
 bool SurfaceFlinger::authenticateSurfaceTexture(
         const sp<ISurfaceTexture>& surfaceTexture) const {
     Mutex::Autolock _l(mStateLock);
@@ -360,20 +384,17 @@
     return false;
 }
 
-status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
-        nsecs_t reltime, uint32_t flags)
-{
-    return mEventQueue.postMessage(msg, reltime, flags);
+// ----------------------------------------------------------------------------
+
+sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
+    sp<DisplayEventConnection> result(new DisplayEventConnection(this));
+    mEventThread->registerDisplayEventConnection(result);
+    return result;
 }
 
-status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
-        nsecs_t reltime, uint32_t flags)
-{
-    status_t res = mEventQueue.postMessage(msg, reltime, flags);
-    if (res == NO_ERROR) {
-        msg->wait();
-    }
-    return res;
+void SurfaceFlinger::cleanupDisplayEventConnection(
+        const wp<DisplayEventConnection>& connection) {
+    mEventThread->unregisterDisplayEventConnection(connection);
 }
 
 // ----------------------------------------------------------------------------
@@ -432,7 +453,7 @@
     } else {
         // pretend we did the post
         hw.compositionComplete();
-        usleep(16667); // 60 fps period
+        hw.waitForVSync();
     }
     return true;
 }
@@ -1572,9 +1593,16 @@
         }
 
         /*
+         * VSYNC state
+         */
+        mEventThread->dump(result, buffer, SIZE);
+
+        /*
          * Dump HWComposer state
          */
         HWComposer& hwc(hw.getHwComposer());
+        snprintf(buffer, SIZE, "h/w composer state:\n");
+        result.append(buffer);
         snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
                 hwc.initCheck()==NO_ERROR ? "present" : "not present",
                 (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");