Merge "Disable hardware vsync when blanking the screen" into klp-dev
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4a1373e..bc8cfb8 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -147,6 +147,7 @@
         mLastTransactionTime(0),
         mBootFinished(false),
         mPrimaryHWVsyncEnabled(false),
+        mHWVsyncAvailable(false),
         mDaltonize(false)
 {
     ALOGI("SurfaceFlinger is starting");
@@ -752,16 +753,23 @@
 
 void SurfaceFlinger::enableHardwareVsync() {
     Mutex::Autolock _l(mHWVsyncLock);
-    if (!mPrimaryHWVsyncEnabled) {
+    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
         mPrimaryDispSync.beginResync();
         eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
         mPrimaryHWVsyncEnabled = true;
     }
 }
 
-void SurfaceFlinger::resyncToHardwareVsync() {
+void SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
     Mutex::Autolock _l(mHWVsyncLock);
 
+    if (makeAvailable) {
+        mHWVsyncAvailable = true;
+    } else if (!mHWVsyncAvailable) {
+        ALOGE("resyncToHardwareVsync called when HW vsync unavailable");
+        return;
+    }
+
     const nsecs_t period =
             getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
 
@@ -775,13 +783,16 @@
     }
 }
 
-void SurfaceFlinger::disableHardwareVsync() {
+void SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
     Mutex::Autolock _l(mHWVsyncLock);
     if (mPrimaryHWVsyncEnabled) {
         eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
         mPrimaryDispSync.endResync();
         mPrimaryHWVsyncEnabled = false;
     }
+    if (makeUnavailable) {
+        mHWVsyncAvailable = false;
+    }
 }
 
 void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
@@ -791,7 +802,7 @@
         if (needsHwVsync) {
             enableHardwareVsync();
         } else {
-            disableHardwareVsync();
+            disableHardwareVsync(false);
         }
     }
 }
@@ -933,7 +944,7 @@
         if (mPrimaryDispSync.addPresentFence(presentFence)) {
             enableHardwareVsync();
         } else {
-            disableHardwareVsync();
+            disableHardwareVsync(false);
         }
     }
 
@@ -2178,7 +2189,7 @@
             // FIXME: eventthread only knows about the main display right now
             mEventThread->onScreenAcquired();
 
-            resyncToHardwareVsync();
+            resyncToHardwareVsync(true);
         }
     }
     mVisibleRegionsDirty = true;
@@ -2196,6 +2207,8 @@
     int32_t type = hw->getDisplayType();
     if (type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
         if (type == DisplayDevice::DISPLAY_PRIMARY) {
+            disableHardwareVsync(true); // also cancels any in-progress resync
+
             // FIXME: eventthread only knows about the main display right now
             mEventThread->onScreenReleased();
         }
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index f1c19c2..353e7ba 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -383,8 +383,8 @@
      * VSync
      */
      void enableHardwareVsync();
-     void disableHardwareVsync();
-     void resyncToHardwareVsync();
+     void disableHardwareVsync(bool makeUnavailable);
+     void resyncToHardwareVsync(bool makeAvailable);
 
     /* ------------------------------------------------------------------------
      * Debugging & dumpsys
@@ -467,6 +467,7 @@
     // protected by mHWVsyncLock
     Mutex mHWVsyncLock;
     bool mPrimaryHWVsyncEnabled;
+    bool mHWVsyncAvailable;
 
     /* ------------------------------------------------------------------------
      * Feature prototyping