Bug 1119742 - Add RefreshTimerDispatcher into VsyncSource::Display. r=kats
authorJerryShih <hshih@mozilla.com>
Tue, 13 Jan 2015 08:04:00 -0500
changeset 223596 bd43663b61a48cd6a243bb89285af16af8ba3dfa
parent 223595 d171761d10c639bfa6d8c82bcd6fd24785107055
child 223597 b4c5a27a1ab474e05191b62814587831094b8d54
push id28098
push userkwierso@gmail.com
push dateWed, 14 Jan 2015 00:52:19 +0000
treeherdermozilla-central@e978b8bc5c45 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1119742
milestone38.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1119742 - Add RefreshTimerDispatcher into VsyncSource::Display. r=kats 1) Create RefreshTimerDispatcher in VsyncSource::Display. 2) Use mutex for all VsyncSource::Display's member access.
gfx/thebes/VsyncSource.cpp
gfx/thebes/VsyncSource.h
--- a/gfx/thebes/VsyncSource.cpp
+++ b/gfx/thebes/VsyncSource.cpp
@@ -1,67 +1,97 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "VsyncSource.h"
-#include "gfxPlatform.h"
-#include "mozilla/TimeStamp.h"
+#include "nsThreadUtils.h"
+#include "nsXULAppAPI.h"
 #include "mozilla/VsyncDispatcher.h"
 #include "MainThreadUtils.h"
 
-using namespace mozilla;
-using namespace mozilla::gfx;
+namespace mozilla {
+namespace gfx {
 
 void
 VsyncSource::AddCompositorVsyncDispatcher(CompositorVsyncDispatcher* aCompositorVsyncDispatcher)
 {
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
+  // Just use the global display until we have enough information to get the
+  // corresponding display for compositor.
   GetGlobalDisplay().AddCompositorVsyncDispatcher(aCompositorVsyncDispatcher);
 }
 
 void
 VsyncSource::RemoveCompositorVsyncDispatcher(CompositorVsyncDispatcher* aCompositorVsyncDispatcher)
 {
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
+  // See also AddCompositorVsyncDispatcher().
   GetGlobalDisplay().RemoveCompositorVsyncDispatcher(aCompositorVsyncDispatcher);
 }
 
-VsyncSource::Display&
-VsyncSource::FindDisplay(CompositorVsyncDispatcher* aCompositorVsyncDispatcher)
+nsRefPtr<RefreshTimerVsyncDispatcher>
+VsyncSource::GetRefreshTimerVsyncDispatcher()
+{
+  MOZ_ASSERT(XRE_IsParentProcess());
+  // See also AddCompositorVsyncDispatcher().
+  return GetGlobalDisplay().GetRefreshTimerVsyncDispatcher();
+}
+
+VsyncSource::Display::Display()
+  : mDispatcherLock("display dispatcher lock")
 {
-  return GetGlobalDisplay();
+  MOZ_ASSERT(NS_IsMainThread());
+  mRefreshTimerVsyncDispatcher = new RefreshTimerVsyncDispatcher();
+}
+
+VsyncSource::Display::~Display()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MutexAutoLock lock(mDispatcherLock);
+  mRefreshTimerVsyncDispatcher = nullptr;
+  mCompositorVsyncDispatchers.Clear();
 }
 
 void
 VsyncSource::Display::NotifyVsync(TimeStamp aVsyncTimestamp)
 {
   // Called on the vsync thread
+  MutexAutoLock lock(mDispatcherLock);
+
   for (size_t i = 0; i < mCompositorVsyncDispatchers.Length(); i++) {
     mCompositorVsyncDispatchers[i]->NotifyVsync(aVsyncTimestamp);
   }
-}
 
-VsyncSource::Display::Display()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-}
-
-VsyncSource::Display::~Display()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  mCompositorVsyncDispatchers.Clear();
+  mRefreshTimerVsyncDispatcher->NotifyVsync(aVsyncTimestamp);
 }
 
 void
 VsyncSource::Display::AddCompositorVsyncDispatcher(CompositorVsyncDispatcher* aCompositorVsyncDispatcher)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  mCompositorVsyncDispatchers.AppendElement(aCompositorVsyncDispatcher);
+  MOZ_ASSERT(aCompositorVsyncDispatcher);
+  MutexAutoLock lock(mDispatcherLock);
+  if (!mCompositorVsyncDispatchers.Contains(aCompositorVsyncDispatcher)) {
+    mCompositorVsyncDispatchers.AppendElement(aCompositorVsyncDispatcher);
+  }
 }
 
 void
 VsyncSource::Display::RemoveCompositorVsyncDispatcher(CompositorVsyncDispatcher* aCompositorVsyncDispatcher)
 {
   MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(aCompositorVsyncDispatcher);
+  MutexAutoLock lock(mDispatcherLock);
   mCompositorVsyncDispatchers.RemoveElement(aCompositorVsyncDispatcher);
 }
+
+nsRefPtr<RefreshTimerVsyncDispatcher>
+VsyncSource::Display::GetRefreshTimerVsyncDispatcher()
+{
+  return mRefreshTimerVsyncDispatcher;
+}
+
+} //namespace gfx
+} //namespace mozilla
--- a/gfx/thebes/VsyncSource.h
+++ b/gfx/thebes/VsyncSource.h
@@ -1,63 +1,78 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_VSYNCSOURCE_H
 #define GFX_VSYNCSOURCE_H
 
-#include "mozilla/RefPtr.h"
+#include "nsTArray.h"
+#include "nsRefPtr.h"
+#include "mozilla/Mutex.h"
 #include "mozilla/TimeStamp.h"
 #include "nsISupportsImpl.h"
-#include "nsTArray.h"
 
 namespace mozilla {
+class RefreshTimerVsyncDispatcher;
 class CompositorVsyncDispatcher;
 
 namespace gfx {
 
 // Controls how and when to enable/disable vsync. Lives as long as the
 // gfxPlatform does on the parent process
 class VsyncSource
 {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VsyncSource)
+
+  typedef mozilla::RefreshTimerVsyncDispatcher RefreshTimerVsyncDispatcher;
+  typedef mozilla::CompositorVsyncDispatcher CompositorVsyncDispatcher;
+
 public:
   // Controls vsync unique to each display and unique on each platform
   class Display {
     public:
       Display();
       virtual ~Display();
-      void AddCompositorVsyncDispatcher(mozilla::CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
-      void RemoveCompositorVsyncDispatcher(mozilla::CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
+
       // Notified when this display's vsync occurs, on the vsync thread
       // The aVsyncTimestamp should normalize to the Vsync time that just occured
       // However, different platforms give different vsync notification times.
       // b2g - The vsync timestamp of the previous frame that was just displayed
       // OSX - The vsync timestamp of the upcoming frame, in the future
       // TODO: Windows / Linux. DOCUMENT THIS WHEN IMPLEMENTING ON THOSE PLATFORMS
       // Android: TODO
       // All platforms should normalize to the vsync that just occured.
       // Large parts of Gecko assume TimeStamps should not be in the future such as animations
-      virtual void NotifyVsync(mozilla::TimeStamp aVsyncTimestamp);
+      virtual void NotifyVsync(TimeStamp aVsyncTimestamp);
+
+      nsRefPtr<RefreshTimerVsyncDispatcher> GetRefreshTimerVsyncDispatcher();
+
+      void AddCompositorVsyncDispatcher(CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
+      void RemoveCompositorVsyncDispatcher(CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
 
       // These should all only be called on the main thread
       virtual void EnableVsync() = 0;
       virtual void DisableVsync() = 0;
       virtual bool IsVsyncEnabled() = 0;
 
     private:
-      nsTArray<nsRefPtr<mozilla::CompositorVsyncDispatcher>> mCompositorVsyncDispatchers;
-  }; // end Display
+      Mutex mDispatcherLock;
+      nsTArray<nsRefPtr<CompositorVsyncDispatcher>> mCompositorVsyncDispatchers;
+      nsRefPtr<RefreshTimerVsyncDispatcher> mRefreshTimerVsyncDispatcher;
+  };
 
-  void AddCompositorVsyncDispatcher(mozilla::CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
-  void RemoveCompositorVsyncDispatcher(mozilla::CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
+  void AddCompositorVsyncDispatcher(CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
+  void RemoveCompositorVsyncDispatcher(CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
+
+  nsRefPtr<RefreshTimerVsyncDispatcher> GetRefreshTimerVsyncDispatcher();
 
 protected:
   virtual Display& GetGlobalDisplay() = 0; // Works across all displays
-  virtual Display& FindDisplay(mozilla::CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
+
   virtual ~VsyncSource() {}
-}; // VsyncSource
-} // gfx
-} // mozilla
+};
+
+} // namespace gfx
+} // namespace mozilla
 
 #endif /* GFX_VSYNCSOURCE_H */