Bug 1160102 - Use VsyncDisplay interface to turn on/off vsync. r=kats, a=bajaj
authorJerryShih <hshih@mozilla.com>
Tue, 12 May 2015 08:12:00 -0400
changeset 238359 7cb9621d7e1bd5383f8b36464416c46b2b71f278
parent 238358 4396f2ab12f057eeff8c38a69f7b66a0c0668c3f
child 238360 eb98876d440b9c1c2e781031b8c6781fd76cbd5f
push id588
push userryanvm@gmail.com
push dateTue, 12 May 2015 18:29:23 +0000
treeherdermozilla-b2g37_v2_2@eb98876d440b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats, bajaj
bugs1160102
milestone37.0
Bug 1160102 - Use VsyncDisplay interface to turn on/off vsync. r=kats, a=bajaj
widget/gonk/nsWindow.cpp
--- a/widget/gonk/nsWindow.cpp
+++ b/widget/gonk/nsWindow.cpp
@@ -49,16 +49,17 @@
 #include "mozilla/layers/APZCTreeManager.h"
 #include "mozilla/layers/APZThreadUtils.h"
 #include "mozilla/layers/CompositorParent.h"
 #include "mozilla/layers/InputAPZContext.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/TouchEvents.h"
 #include "nsThreadUtils.h"
 #include "HwcComposer2D.h"
+#include "VsyncSource.h"
 
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
 #define LOGW(args...) __android_log_print(ANDROID_LOG_WARN, "Gonk", ## args)
 #define LOGE(args...) __android_log_print(ANDROID_LOG_ERROR, "Gonk", ## args)
 
 #define IS_TOPLEVEL() (mWindowType == eWindowType_toplevel || mWindowType == eWindowType_dialog)
 
 using namespace mozilla;
@@ -120,23 +121,65 @@ public:
 
         return NS_OK;
     }
 
 private:
     bool mIsOn;
 };
 
+class VsyncControlRunnable : public nsRunnable
+{
+public:
+    VsyncControlRunnable(bool aEnabled)
+        : mEnabled(aEnabled)
+    {
+    }
+
+    NS_IMETHOD Run()
+    {
+        VsyncControl(mEnabled);
+
+        return NS_OK;
+    }
+
+    static void VsyncControl(bool aEnabled)
+    {
+        MOZ_ASSERT(gfxPrefs::HardwareVsyncEnabled());
+        MOZ_ASSERT(NS_IsMainThread());
+
+        VsyncSource::Display &display =
+            gfxPlatform::GetPlatform()->GetHardwareVsync()->GetGlobalDisplay();
+        if (aEnabled) {
+            display.EnableVsync();
+        } else {
+            display.DisableVsync();
+        }
+    }
+
+private:
+    bool mEnabled;
+};
+
 static StaticRefPtr<ScreenOnOffEvent> sScreenOnEvent;
 static StaticRefPtr<ScreenOnOffEvent> sScreenOffEvent;
+static StaticRefPtr<VsyncControlRunnable> sVsyncOnRunnable;
+static StaticRefPtr<VsyncControlRunnable> sVsyncOffRunnable;
 
 static void
 displayEnabledCallback(bool enabled)
 {
-    HwcComposer2D::GetInstance()->EnableVsync(enabled);
+    if (gfxPrefs::HardwareVsyncEnabled()) {
+        if (NS_IsMainThread()) {
+            VsyncControlRunnable::VsyncControl(enabled);
+        } else {
+            NS_DispatchToMainThread(enabled ? sVsyncOnRunnable : sVsyncOffRunnable);
+        }
+    }
+
     NS_DispatchToMainThread(enabled ? sScreenOnEvent : sScreenOffEvent);
 }
 
 } // anonymous namespace
 
 NS_IMPL_ISUPPORTS_INHERITED(nsWindow, nsBaseWidget, nsISupportsWeakReference)
 
 nsWindow::nsWindow()
@@ -145,16 +188,21 @@ nsWindow::nsWindow()
 
     if (sScreenInitialized)
         return;
 
     sScreenOnEvent = new ScreenOnOffEvent(true);
     ClearOnShutdown(&sScreenOnEvent);
     sScreenOffEvent = new ScreenOnOffEvent(false);
     ClearOnShutdown(&sScreenOffEvent);
+    sVsyncOnRunnable = new VsyncControlRunnable(true);
+    ClearOnShutdown(&sVsyncOnRunnable);
+    sVsyncOffRunnable = new VsyncControlRunnable(false);
+    ClearOnShutdown(&sVsyncOffRunnable);
+
     GetGonkDisplay()->OnEnabled(displayEnabledCallback);
 
     nsIntSize screenSize;
 
     ANativeWindow *win = GetGonkDisplay()->GetNativeWindow();
 
     if (win->query(win, NATIVE_WINDOW_WIDTH, &screenSize.width) ||
         win->query(win, NATIVE_WINDOW_HEIGHT, &screenSize.height)) {