Bug 1119742 - Add RefreshTimerDispatcher into VsyncSource::Display. r=kats, a=bajaj
authorJerryShih <hshih@mozilla.com>
Tue, 13 Jan 2015 21:05:00 -0500
changeset 232167 ce27f2692382ba096b97debfc29df602ee936e3d
parent 232166 5453ae19d3f66a0271a7405473374d763824e295
child 232168 8a003bc7632ecf5ecf56024dd7a1dc02454dcd02
push id13
push userryanvm@gmail.com
push dateWed, 14 Jan 2015 22:01:23 +0000
treeherdermozilla-b2g37_v2_2@ce27f2692382 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats, bajaj
bugs1119742
milestone37.0a2
Bug 1119742 - Add RefreshTimerDispatcher into VsyncSource::Display. r=kats, a=bajaj 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,55 +1,70 @@
 /* -*- 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
-      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 */