SurfaceFlinger now uses the new VSYNC HAL API.

If h/w composer doesn't support vsync (version < 0.3) we
"fake" it with a timer.

Change-Id: I1e3be79f43c9631d1293ad7d6cf52f9bfc42d65b
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index 97afb5f..b05b7c2 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -38,13 +38,15 @@
 
 EventThread::EventThread(const sp<SurfaceFlinger>& flinger)
     : mFlinger(flinger),
-      mHw(flinger->graphicPlane(0).displayHardware()),
+      mHw(flinger->graphicPlane(0).editDisplayHardware()),
       mLastVSyncTimestamp(0),
+      mVSyncTimestamp(0),
       mDeliveredEvents(0)
 {
 }
 
 void EventThread::onFirstRef() {
+    mHw.setVSyncHandler(this);
     run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
 }
 
@@ -105,76 +107,89 @@
     }
 }
 
+void EventThread::onVSyncReceived(int, nsecs_t timestamp) {
+    Mutex::Autolock _l(mLock);
+    mVSyncTimestamp = timestamp;
+    mCondition.signal();
+}
+
 bool EventThread::threadLoop() {
 
     nsecs_t timestamp;
     DisplayEventReceiver::Event vsync;
     Vector< wp<EventThread::Connection> > displayEventConnections;
 
-    { // scope for the lock
+    do {
+
         Mutex::Autolock _l(mLock);
         do {
-            // see if we need to wait for the VSYNC at all
-            do {
-                bool waitForNextVsync = false;
-                size_t count = mDisplayEventConnections.size();
-                for (size_t i=0 ; i<count ; i++) {
-                    sp<Connection> connection =
-                            mDisplayEventConnections.itemAt(i).promote();
-                    if (connection!=0 && connection->count >= 0) {
-                        // at least one continuous mode or active one-shot event
-                        waitForNextVsync = true;
-                        break;
-                    }
-                }
+            // check if we have received a VSYNC event
+            if (mVSyncTimestamp) {
+                // we have a VSYNC event pending
+                timestamp = mVSyncTimestamp;
+                mVSyncTimestamp = 0;
+                break;
+            }
 
-                if (waitForNextVsync)
-                    break;
-
-                mCondition.wait(mLock);
-            } while(true);
-
-            // at least one listener requested VSYNC
-            mLock.unlock();
-            timestamp = mHw.waitForRefresh();
-            ATRACE_INT("VSYNC", mDeliveredEvents&1);
-            mLock.lock();
-            mDeliveredEvents++;
-            mLastVSyncTimestamp = timestamp;
-
-            // now see if we still need to report this VSYNC event
-            const size_t count = mDisplayEventConnections.size();
+            // check if we should be waiting for VSYNC events
+            bool waitForNextVsync = false;
+            size_t count = mDisplayEventConnections.size();
             for (size_t i=0 ; i<count ; i++) {
-                bool reportVsync = false;
                 sp<Connection> connection =
                         mDisplayEventConnections.itemAt(i).promote();
-                if (connection == 0)
-                    continue;
-
-                const int32_t count = connection->count;
-                if (count >= 1) {
-                    if (count==1 || (mDeliveredEvents % count) == 0) {
-                        // continuous event, and time to report it
-                        reportVsync = true;
-                    }
-                } else if (count >= -1) {
-                    if (count == 0) {
-                        // fired this time around
-                        reportVsync = true;
-                    }
-                    connection->count--;
-                }
-                if (reportVsync) {
-                    displayEventConnections.add(connection);
+                if (connection!=0 && connection->count >= 0) {
+                    // at least one continuous mode or active one-shot event
+                    waitForNextVsync = true;
+                    break;
                 }
             }
-        } while (!displayEventConnections.size());
 
-        // dispatch vsync events to listeners...
-        vsync.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
-        vsync.header.timestamp = timestamp;
-        vsync.vsync.count = mDeliveredEvents;
-    }
+            // enable or disable VSYNC events
+            mHw.getHwComposer().eventControl(
+                    HWComposer::EVENT_VSYNC, waitForNextVsync);
+
+            // wait for something to happen
+            mCondition.wait(mLock);
+        } while(true);
+
+        // process vsync event
+
+        ATRACE_INT("VSYNC", mDeliveredEvents&1);
+        mDeliveredEvents++;
+        mLastVSyncTimestamp = timestamp;
+
+        // now see if we still need to report this VSYNC event
+        const size_t count = mDisplayEventConnections.size();
+        for (size_t i=0 ; i<count ; i++) {
+            bool reportVsync = false;
+            sp<Connection> connection =
+                    mDisplayEventConnections.itemAt(i).promote();
+            if (connection == 0)
+                continue;
+
+            const int32_t count = connection->count;
+            if (count >= 1) {
+                if (count==1 || (mDeliveredEvents % count) == 0) {
+                    // continuous event, and time to report it
+                    reportVsync = true;
+                }
+            } else if (count >= -1) {
+                if (count == 0) {
+                    // fired this time around
+                    reportVsync = true;
+                }
+                connection->count--;
+            }
+            if (reportVsync) {
+                displayEventConnections.add(connection);
+            }
+        }
+    } while (!displayEventConnections.size());
+
+    // dispatch vsync events to listeners...
+    vsync.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
+    vsync.header.timestamp = timestamp;
+    vsync.vsync.count = mDeliveredEvents;
 
     const size_t count = displayEventConnections.size();
     for (size_t i=0 ; i<count ; i++) {