Bug 1276931. Add VsyncSource::Shutdown which shuts down global display. r=jrmuizel, a=sylvestre
authorMason Chang <mchang@mozilla.com>
Mon, 06 Jun 2016 10:07:29 -0700
changeset 339608 dca560586c399c3ae3a7ce96d5c3681ee2cbf5b4
parent 339607 73286271d4769104a91633e8ae9fd50f0d090d1d
child 339609 8c7667ce0a8d9c37318c19cbfdfaa34db9d409cc
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel, sylvestre
bugs1276931
milestone49.0a2
Bug 1276931. Add VsyncSource::Shutdown which shuts down global display. r=jrmuizel, a=sylvestre
gfx/thebes/SoftwareVsyncSource.cpp
gfx/thebes/SoftwareVsyncSource.h
gfx/thebes/VsyncSource.cpp
gfx/thebes/VsyncSource.h
gfx/thebes/gfxAndroidPlatform.cpp
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxPlatformMac.cpp
gfx/thebes/gfxWindowsPlatform.cpp
--- a/gfx/thebes/SoftwareVsyncSource.cpp
+++ b/gfx/thebes/SoftwareVsyncSource.cpp
@@ -15,17 +15,16 @@ SoftwareVsyncSource::SoftwareVsyncSource
 {
   MOZ_ASSERT(NS_IsMainThread());
   mGlobalDisplay = new SoftwareDisplay();
 }
 
 SoftwareVsyncSource::~SoftwareVsyncSource()
 {
   MOZ_ASSERT(NS_IsMainThread());
-  mGlobalDisplay->Shutdown();
   mGlobalDisplay = nullptr;
 }
 
 SoftwareDisplay::SoftwareDisplay()
   : mVsyncEnabled(false)
 {
   // Mimic 60 fps
   MOZ_ASSERT(NS_IsMainThread());
--- a/gfx/thebes/SoftwareVsyncSource.h
+++ b/gfx/thebes/SoftwareVsyncSource.h
@@ -22,17 +22,17 @@ public:
   SoftwareDisplay();
   virtual void EnableVsync() override;
   virtual void DisableVsync() override;
   virtual bool IsVsyncEnabled() override;
   bool IsInSoftwareVsyncThread();
   virtual void NotifyVsync(mozilla::TimeStamp aVsyncTimestamp) override;
   virtual mozilla::TimeDuration GetVsyncRate() override;
   void ScheduleNextVsync(mozilla::TimeStamp aVsyncTimestamp);
-  void Shutdown();
+  void Shutdown() override;
 
 protected:
   ~SoftwareDisplay();
 
 private:
   mozilla::TimeDuration mVsyncRate;
   // Use a chromium thread because nsITimers* fire on the main thread
   base::Thread* mVsyncThread;
--- a/gfx/thebes/VsyncSource.cpp
+++ b/gfx/thebes/VsyncSource.cpp
@@ -138,10 +138,16 @@ VsyncSource::Display::UpdateVsyncStatus(
 }
 
 RefPtr<RefreshTimerVsyncDispatcher>
 VsyncSource::Display::GetRefreshTimerVsyncDispatcher()
 {
   return mRefreshTimerVsyncDispatcher;
 }
 
+void
+VsyncSource::Shutdown()
+{
+  GetGlobalDisplay().Shutdown();
+}
+
 } //namespace gfx
 } //namespace mozilla
--- a/gfx/thebes/VsyncSource.h
+++ b/gfx/thebes/VsyncSource.h
@@ -51,31 +51,33 @@ public:
       void RemoveCompositorVsyncDispatcher(CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
       void NotifyRefreshTimerVsyncStatus(bool aEnable);
       virtual TimeDuration GetVsyncRate();
 
       // These should all only be called on the main thread
       virtual void EnableVsync() = 0;
       virtual void DisableVsync() = 0;
       virtual bool IsVsyncEnabled() = 0;
+      virtual void Shutdown() = 0;
 
     private:
       void UpdateVsyncStatus();
 
       Mutex mDispatcherLock;
       bool mRefreshTimerNeedsVsync;
       nsTArray<RefPtr<CompositorVsyncDispatcher>> mCompositorVsyncDispatchers;
       RefPtr<RefreshTimerVsyncDispatcher> mRefreshTimerVsyncDispatcher;
   };
 
   void AddCompositorVsyncDispatcher(CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
   void RemoveCompositorVsyncDispatcher(CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
 
   RefPtr<RefreshTimerVsyncDispatcher> GetRefreshTimerVsyncDispatcher();
   virtual Display& GetGlobalDisplay() = 0; // Works across all displays
+  void Shutdown();
 
 protected:
   virtual ~VsyncSource() {}
 };
 
 } // namespace gfx
 } // namespace mozilla
 
--- a/gfx/thebes/gfxAndroidPlatform.cpp
+++ b/gfx/thebes/gfxAndroidPlatform.cpp
@@ -378,16 +378,22 @@ public:
   {
   public:
     GonkDisplay() : mVsyncEnabled(false)
     {
     }
 
     ~GonkDisplay()
     {
+      MOZ_ASSERT(NS_IsMainThread());
+    }
+
+    virtual void Shutdown() override
+    {
+      MOZ_ASSERT(NS_IsMainThread());
       DisableVsync();
     }
 
     virtual void EnableVsync() override
     {
       MOZ_ASSERT(NS_IsMainThread());
       if (IsVsyncEnabled()) {
         return;
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -780,16 +780,18 @@ gfxPlatform::Init()
     }
 }
 
 static bool sLayersIPCIsUp = false;
 
 void
 gfxPlatform::Shutdown()
 {
+    // In some cases, gPlatform may not be created but Shutdown() called,
+    // e.g., during xpcshell tests.
     if (!gPlatform) {
       return;
     }
 
     MOZ_ASSERT(!sLayersIPCIsUp);
 
     // These may be called before the corresponding subsystems have actually
     // started up. That's OK, they can handle it.
@@ -799,39 +801,40 @@ gfxPlatform::Shutdown()
     gfxAlphaBoxBlur::ShutdownBlurCache();
     gfxGraphiteShaper::Shutdown();
     gfxPlatformFontList::Shutdown();
     ShutdownTileCache();
 
     // Free the various non-null transforms and loaded profiles
     ShutdownCMS();
 
-    // In some cases, gPlatform may not be created but Shutdown() called,
-    // e.g., during xpcshell tests.
-    if (gPlatform) {
-        /* Unregister our CMS Override callback. */
-        NS_ASSERTION(gPlatform->mSRGBOverrideObserver, "mSRGBOverrideObserver has alreay gone");
-        Preferences::RemoveObserver(gPlatform->mSRGBOverrideObserver, GFX_PREF_CMS_FORCE_SRGB);
-        gPlatform->mSRGBOverrideObserver = nullptr;
+    /* Unregister our CMS Override callback. */
+    NS_ASSERTION(gPlatform->mSRGBOverrideObserver, "mSRGBOverrideObserver has alreay gone");
+    Preferences::RemoveObserver(gPlatform->mSRGBOverrideObserver, GFX_PREF_CMS_FORCE_SRGB);
+    gPlatform->mSRGBOverrideObserver = nullptr;
+
+    NS_ASSERTION(gPlatform->mFontPrefsObserver, "mFontPrefsObserver has alreay gone");
+    Preferences::RemoveObservers(gPlatform->mFontPrefsObserver, kObservedPrefs);
+    gPlatform->mFontPrefsObserver = nullptr;
 
-        NS_ASSERTION(gPlatform->mFontPrefsObserver, "mFontPrefsObserver has alreay gone");
-        Preferences::RemoveObservers(gPlatform->mFontPrefsObserver, kObservedPrefs);
-        gPlatform->mFontPrefsObserver = nullptr;
+    NS_ASSERTION(gPlatform->mMemoryPressureObserver, "mMemoryPressureObserver has already gone");
+    nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+    if (obs) {
+        obs->RemoveObserver(gPlatform->mMemoryPressureObserver, "memory-pressure");
+    }
 
-        NS_ASSERTION(gPlatform->mMemoryPressureObserver, "mMemoryPressureObserver has already gone");
-        nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
-        if (obs) {
-            obs->RemoveObserver(gPlatform->mMemoryPressureObserver, "memory-pressure");
-        }
+    gPlatform->mMemoryPressureObserver = nullptr;
+    gPlatform->mSkiaGlue = nullptr;
 
-        gPlatform->mMemoryPressureObserver = nullptr;
-        gPlatform->mSkiaGlue = nullptr;
-        gPlatform->mVsyncSource = nullptr;
+    if (XRE_IsParentProcess()) {
+      gPlatform->mVsyncSource->Shutdown();
     }
 
+    gPlatform->mVsyncSource = nullptr;
+
 #ifdef MOZ_WIDGET_ANDROID
     // Shut down the texture pool
     TexturePoolOGL::Shutdown();
 #endif
 
     // Shut down the default GL context provider.
     GLContextProvider::Shutdown();
 
--- a/gfx/thebes/gfxPlatformMac.cpp
+++ b/gfx/thebes/gfxPlatformMac.cpp
@@ -412,19 +412,16 @@ public:
     {
       MOZ_ASSERT(NS_IsMainThread());
       mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
     }
 
     ~OSXDisplay()
     {
       MOZ_ASSERT(NS_IsMainThread());
-      mTimer->Cancel();
-      mTimer = nullptr;
-      DisableVsync();
     }
 
     static void RetryEnableVsync(nsITimer* aTimer, void* aOsxDisplay)
     {
       MOZ_ASSERT(NS_IsMainThread());
       OSXDisplay* osxDisplay = static_cast<OSXDisplay*>(aOsxDisplay);
       MOZ_ASSERT(osxDisplay);
       osxDisplay->EnableVsync();
@@ -510,16 +507,24 @@ public:
       return mDisplayLink != nullptr;
     }
 
     virtual TimeDuration GetVsyncRate() override
     {
       return mVsyncRate;
     }
 
+    virtual void Shutdown() override
+    {
+      MOZ_ASSERT(NS_IsMainThread());
+      mTimer->Cancel();
+      mTimer = nullptr;
+      DisableVsync();
+    }
+
     // The vsync timestamps given by the CVDisplayLinkCallback are
     // in the future for the NEXT frame. Large parts of Gecko, such
     // as animations assume a timestamp at either now or in the past.
     // Normalize the timestamps given to the VsyncDispatchers to the vsync
     // that just occured, not the vsync that is upcoming.
     TimeStamp mPreviousTimestamp;
 
   private:
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -2727,16 +2727,24 @@ public:
           float rate = ((float) refreshRate.uiDenominator
                        / (float) refreshRate.uiNumerator) * 1000;
           mVsyncRate = TimeDuration::FromMilliseconds(rate);
         } else {
           mVsyncRate = TimeDuration::FromMilliseconds(1000.0 / 60.0);
         }
       }
 
+      virtual void Shutdown() override
+      {
+        MOZ_ASSERT(NS_IsMainThread());
+        DisableVsync();
+        mVsyncThread->Stop();
+        delete mVsyncThread;
+      }
+
       virtual void EnableVsync() override
       {
         MOZ_ASSERT(NS_IsMainThread());
         MOZ_ASSERT(mVsyncThread->IsRunning());
         { // scope lock
           MonitorAutoLock lock(mVsyncEnabledLock);
           if (mVsyncEnabled) {
             return;
@@ -2889,19 +2897,16 @@ public:
                     TimeStamp::Now();
         } // end for
       }
 
     private:
       virtual ~D3DVsyncDisplay()
       {
         MOZ_ASSERT(NS_IsMainThread());
-        DisableVsync();
-        mVsyncThread->Stop();
-        delete mVsyncThread;
       }
 
       bool IsInVsyncThread()
       {
         return mVsyncThread->thread_id() == PlatformThread::CurrentId();
       }
 
       TimeDuration mSoftwareVsyncRate;