make sure to disable VSYNC while screen is off

Change-Id: If1894c43b0a39a2851e1280a35ae77bccd6d9abd
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index 5813eefb..d86c280 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -41,6 +41,7 @@
       mHw(flinger->graphicPlane(0).editDisplayHardware()),
       mLastVSyncTimestamp(0),
       mVSyncTimestamp(0),
+      mUseSoftwareVSync(false),
       mDeliveredEvents(0),
       mDebugVsyncEnabled(false)
 {
@@ -55,16 +56,6 @@
     return new Connection(const_cast<EventThread*>(this));
 }
 
-nsecs_t EventThread::getLastVSyncTimestamp() const {
-    Mutex::Autolock _l(mLock);
-    return mLastVSyncTimestamp;
-}
-
-nsecs_t EventThread::getVSyncPeriod() const {
-    return mHw.getRefreshPeriod();
-
-}
-
 status_t EventThread::registerDisplayEventConnection(
         const sp<EventThread::Connection>& connection) {
     Mutex::Autolock _l(mLock);
@@ -108,6 +99,24 @@
     }
 }
 
+void EventThread::onScreenReleased() {
+    Mutex::Autolock _l(mLock);
+    // wait for an eventual pending vsync to be serviced
+    if (!mUseSoftwareVSync) {
+        while (mVSyncTimestamp) {
+            mCondition.wait(mLock);
+        }
+    }
+    // disable reliance on h/w vsync
+    mUseSoftwareVSync = true;
+}
+
+void EventThread::onScreenAcquired() {
+    Mutex::Autolock _l(mLock);
+    mUseSoftwareVSync = false;
+}
+
+
 void EventThread::onVSyncReceived(int, nsecs_t timestamp) {
     Mutex::Autolock _l(mLock);
     mVSyncTimestamp = timestamp;
@@ -121,7 +130,6 @@
     Vector< wp<EventThread::Connection> > displayEventConnections;
 
     do {
-
         Mutex::Autolock _l(mLock);
         do {
             // latch VSYNC event if any
@@ -145,7 +153,7 @@
                 if (!waitForNextVsync) {
                     // we received a VSYNC but we have no clients
                     // don't report it, and disable VSYNC events
-                    disableVSync();
+                    disableVSyncLocked();
                 } else {
                     // report VSYNC event
                     break;
@@ -157,12 +165,21 @@
                 // disable VSYNC events then.
                 if (waitForNextVsync) {
                     // enable
-                    enableVSync();
+                    enableVSyncLocked();
                 }
             }
 
             // wait for something to happen
-            mCondition.wait(mLock);
+            if (mUseSoftwareVSync == true) {
+                // h/w vsync cannot be used (screen is off), so we use
+                // a  timeout instead. it doesn't matter how imprecise this
+                // is, we just need to make sure to serve the clients
+                if (mCondition.waitRelative(mLock, ms2ns(16)) == TIMED_OUT) {
+                    mVSyncTimestamp = systemTime(SYSTEM_TIME_MONOTONIC);
+                }
+            } else {
+                mCondition.wait(mLock);
+            }
         } while(true);
 
         // process vsync event
@@ -233,12 +250,15 @@
     return true;
 }
 
-void EventThread::enableVSync() {
-    mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, true);
+void EventThread::enableVSyncLocked() {
+    if (!mUseSoftwareVSync) {
+        // never enable h/w VSYNC when screen is off
+        mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, true);
+    }
     mDebugVsyncEnabled = true;
 }
 
-void EventThread::disableVSync() {
+void EventThread::disableVSyncLocked() {
     mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, false);
     mDebugVsyncEnabled = false;
 }
@@ -252,6 +272,8 @@
     Mutex::Autolock _l(mLock);
     result.appendFormat("VSYNC state: %s\n",
             mDebugVsyncEnabled?"enabled":"disabled");
+    result.appendFormat("  soft-vsync: %s\n",
+            mUseSoftwareVSync?"enabled":"disabled");
     result.appendFormat("  numListeners=%u,\n  events-delivered: %u\n",
             mDisplayEventConnections.size(), mDeliveredEvents);
     for (size_t i=0 ; i<mDisplayEventConnections.size() ; i++) {