Use CompositorWidgetProxy for dispatching vsync to the compositor. (bug 1269037 part 1, r=mchang)
authorDavid Anderson <danderson@mozilla.com>
Tue, 03 May 2016 17:39:23 -0700
changeset 296038 a5086ab888367112761074071ce56ce95ca7a113
parent 296037 2872b9050cab51f33bc0d95b72461a990b80dd34
child 296039 ff82b00b481ed96257bd93ce3e28e882a2f292b6
push id30230
push usercbook@mozilla.com
push dateWed, 04 May 2016 09:55:16 +0000
treeherdermozilla-central@311c7ea8803d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmchang
bugs1269037
milestone49.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
Use CompositorWidgetProxy for dispatching vsync to the compositor. (bug 1269037 part 1, r=mchang)
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/ipc/CompositorBridgeParent.h
widget/CompositorWidgetProxy.cpp
widget/CompositorWidgetProxy.h
widget/nsBaseWidget.h
widget/nsIWidget.h
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -300,38 +300,38 @@ CompositorVsyncScheduler::Observer::Noti
 
 void
 CompositorVsyncScheduler::Observer::Destroy()
 {
   MutexAutoLock lock(mMutex);
   mOwner = nullptr;
 }
 
-CompositorVsyncScheduler::CompositorVsyncScheduler(CompositorBridgeParent* aCompositorBridgeParent, nsIWidget* aWidget)
+CompositorVsyncScheduler::CompositorVsyncScheduler(CompositorBridgeParent* aCompositorBridgeParent,
+                                                   widget::CompositorWidgetProxy* aWidgetProxy)
   : mCompositorBridgeParent(aCompositorBridgeParent)
   , mLastCompose(TimeStamp::Now())
   , mIsObservingVsync(false)
   , mNeedsComposite(0)
   , mVsyncNotificationsSkipped(0)
+  , mCompositorVsyncDispatcher(aWidgetProxy->GetCompositorVsyncDispatcher())
   , mCurrentCompositeTaskMonitor("CurrentCompositeTaskMonitor")
   , mCurrentCompositeTask(nullptr)
   , mSetNeedsCompositeMonitor("SetNeedsCompositeMonitor")
   , mSetNeedsCompositeTask(nullptr)
 #ifdef MOZ_WIDGET_GONK
 #if ANDROID_VERSION >= 19
   , mDisplayEnabled(false)
   , mSetDisplayMonitor("SetDisplayMonitor")
   , mSetDisplayTask(nullptr)
 #endif
 #endif
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(aWidget != nullptr);
   mVsyncObserver = new Observer(this);
-  mCompositorVsyncDispatcher = aWidget->GetCompositorVsyncDispatcher();
 #ifdef MOZ_WIDGET_GONK
   GeckoTouchDispatcher::GetInstance()->SetCompositorVsyncScheduler(this);
 
 #if ANDROID_VERSION >= 19
   RefPtr<nsScreenManagerGonk> screenManager = nsScreenManagerGonk::GetInstance();
   screenManager->SetCompositorVsyncScheduler(this);
 #endif
 #endif
@@ -343,17 +343,16 @@ CompositorVsyncScheduler::CompositorVsyn
 }
 
 CompositorVsyncScheduler::~CompositorVsyncScheduler()
 {
   MOZ_ASSERT(!mIsObservingVsync);
   MOZ_ASSERT(!mVsyncObserver);
   // The CompositorVsyncDispatcher is cleaned up before this in the nsBaseWidget, which stops vsync listeners
   mCompositorBridgeParent = nullptr;
-  mCompositorVsyncDispatcher = nullptr;
 }
 
 #ifdef MOZ_WIDGET_GONK
 #if ANDROID_VERSION >= 19
 void
 CompositorVsyncScheduler::SetDisplay(bool aDisplayEnable)
 {
   // SetDisplay() is usually called from nsScreenManager at main thread. Post
@@ -728,17 +727,17 @@ CompositorBridgeParent::CompositorBridge
     MonitorAutoLock lock(*sIndirectLayerTreesLock);
     sIndirectLayerTrees[mRootLayerTreeID].mParent = this;
   }
 
   if (aUseAPZ) {
     mApzcTreeManager = new APZCTreeManager();
   }
 
-  mCompositorScheduler = new CompositorVsyncScheduler(this, aWidget->RealWidget());
+  mCompositorScheduler = new CompositorVsyncScheduler(this, aWidget);
   LayerScope::SetPixelScale(aScale.scale);
 
   // mSelfRef is cleared in DeferredDestroy.
   mSelfRef = this;
 }
 
 bool
 CompositorBridgeParent::IsInCompositorThread()
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -105,17 +105,18 @@ private:
  * compositor when it need to paint.
  * Turns vsync notifications into scheduled composites.
  **/
 class CompositorVsyncScheduler
 {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorVsyncScheduler)
 
 public:
-  explicit CompositorVsyncScheduler(CompositorBridgeParent* aCompositorBridgeParent, nsIWidget* aWidget);
+  explicit CompositorVsyncScheduler(CompositorBridgeParent* aCompositorBridgeParent,
+                                    widget::CompositorWidgetProxy* aWidgetProxy);
 
 #ifdef MOZ_WIDGET_GONK
   // emulator-ics never trigger the display on/off, so compositor will always
   // skip composition request at that device. Only check the display status
   // with kk device and upon.
 #if ANDROID_VERSION >= 19
   // SetDisplay() and CancelSetDisplayTask() are used for the display on/off.
   // It will clear all composition related task and flag, and skip another
--- a/widget/CompositorWidgetProxy.cpp
+++ b/widget/CompositorWidgetProxy.cpp
@@ -1,15 +1,16 @@
 /* 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 "CompositorWidgetProxy.h"
 #include "GLConsts.h"
 #include "nsBaseWidget.h"
+#include "VsyncDispatcher.h"
 
 namespace mozilla {
 namespace widget {
 
 CompositorWidgetProxy::~CompositorWidgetProxy()
 {
 }
 
@@ -197,10 +198,20 @@ CompositorWidgetProxyWrapper::GetCompose
 }
 
 nsIWidget*
 CompositorWidgetProxyWrapper::RealWidget()
 {
   return mWidget;
 }
 
+already_AddRefed<CompositorVsyncDispatcher>
+CompositorWidgetProxyWrapper::GetCompositorVsyncDispatcher()
+{
+  if (!mWidget) {
+    return nullptr;
+  }
+  RefPtr<CompositorVsyncDispatcher> cvd = mWidget->GetCompositorVsyncDispatcher();
+  return cvd.forget();
+}
+
 } // namespace widget
 } // namespace mozilla
--- a/widget/CompositorWidgetProxy.h
+++ b/widget/CompositorWidgetProxy.h
@@ -10,16 +10,17 @@
 #include "Units.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/layers/LayersTypes.h"
 
 class nsIWidget;
 class nsBaseWidget;
 
 namespace mozilla {
+class CompositorVsyncDispatcher;
 namespace layers {
 class Compositor;
 class LayerManagerComposite;
 class Compositor;
 class Composer2D;
 } // namespace layers
 namespace gfx {
 class DrawTarget;
@@ -165,16 +166,21 @@ public:
   /**
    * Create a backbuffer for the software compositor.
    */
   virtual already_AddRefed<gfx::DrawTarget>
   CreateBackBufferDrawTarget(gfx::DrawTarget* aScreenTarget,
                              const LayoutDeviceIntRect& aRect,
                              const LayoutDeviceIntRect& aClearRect);
 
+  /**
+   * Return a compositor vsync dispatcher for this widget.
+   */
+  virtual already_AddRefed<CompositorVsyncDispatcher> GetCompositorVsyncDispatcher() = 0;
+
 protected:
   virtual ~CompositorWidgetProxy();
 
 private:
   // Back buffer of BasicCompositor
   RefPtr<gfx::DrawTarget> mLastBackBuffer;
 };
 
@@ -199,16 +205,17 @@ public:
   virtual void EndRemoteDrawingInRegion(gfx::DrawTarget* aDrawTarget,
                                         LayoutDeviceIntRegion& aInvalidRegion) override;
   virtual void CleanupRemoteDrawing() override;
   virtual void CleanupWindowEffects() override;
   virtual bool InitCompositor(layers::Compositor* aCompositor) override;
   virtual LayoutDeviceIntSize GetClientSize() override;
   virtual uint32_t GetGLFrameBufferFormat() override;
   virtual layers::Composer2D* GetComposer2D() override;
+  virtual already_AddRefed<CompositorVsyncDispatcher> GetCompositorVsyncDispatcher() override;
 
   // If you can override this method, inherit from CompositorWidgetProxy instead.
   nsIWidget* RealWidget() override;
 
 private:
   nsBaseWidget* mWidget;
 };
 
--- a/widget/nsBaseWidget.h
+++ b/widget/nsBaseWidget.h
@@ -23,16 +23,17 @@
 #include "nsWeakReference.h"
 #include "CompositorWidgetProxy.h"
 #include <algorithm>
 class nsIContent;
 class nsAutoRollup;
 class gfxContext;
 
 namespace mozilla {
+class CompositorVsyncDispatcher;
 #ifdef ACCESSIBILITY
 namespace a11y {
 class Accessible;
 }
 #endif
 
 namespace gfx {
 class DrawTarget;
@@ -162,17 +163,17 @@ public:
                                            nsIRunnable* aCallback) override;
   NS_IMETHOD              MakeFullScreen(bool aFullScreen, nsIScreen* aScreen = nullptr) override;
 
   virtual LayerManager*   GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr,
                                           LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE,
                                           LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
                                           bool* aAllowRetaining = nullptr) override;
 
-  CompositorVsyncDispatcher* GetCompositorVsyncDispatcher() override;
+  mozilla::CompositorVsyncDispatcher* GetCompositorVsyncDispatcher();
   void            CreateCompositorVsyncDispatcher();
   virtual CompositorBridgeParent* NewCompositorBridgeParent(int aSurfaceWidth, int aSurfaceHeight);
   virtual void            CreateCompositor();
   virtual void            CreateCompositor(int aWidth, int aHeight);
   virtual void            PrepareWindowEffects() override {}
   virtual void            UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries) override {}
   NS_IMETHOD              SetModal(bool aModal) override;
   virtual uint32_t        GetMaxTouchPoints() const override;
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -37,17 +37,16 @@ class   nsIRollupListener;
 class   imgIContainer;
 class   nsIContent;
 class   ViewWrapper;
 class   nsIScreen;
 class   nsIRunnable;
 class   nsIKeyEventInPluginCallback;
 
 namespace mozilla {
-class CompositorVsyncDispatcher;
 namespace dom {
 class TabChild;
 } // namespace dom
 namespace plugins {
 class PluginWidgetChild;
 } // namespace plugins
 namespace layers {
 class AsyncDragMetrics;
@@ -342,17 +341,16 @@ class nsIWidget : public nsISupports
     typedef mozilla::widget::IMEState IMEState;
     typedef mozilla::widget::InputContext InputContext;
     typedef mozilla::widget::InputContextAction InputContextAction;
     typedef mozilla::widget::NativeIMEContext NativeIMEContext;
     typedef mozilla::widget::SizeConstraints SizeConstraints;
     typedef mozilla::widget::TextEventDispatcher TextEventDispatcher;
     typedef mozilla::widget::TextEventDispatcherListener
       TextEventDispatcherListener;
-    typedef mozilla::CompositorVsyncDispatcher CompositorVsyncDispatcher;
     typedef mozilla::LayoutDeviceIntMargin LayoutDeviceIntMargin;
     typedef mozilla::LayoutDeviceIntPoint LayoutDeviceIntPoint;
     typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect;
     typedef mozilla::LayoutDeviceIntRegion LayoutDeviceIntRegion;
     typedef mozilla::LayoutDeviceIntSize LayoutDeviceIntSize;
     typedef mozilla::ScreenIntPoint ScreenIntPoint;
     typedef mozilla::DesktopIntRect DesktopIntRect;
     typedef mozilla::CSSRect CSSRect;
@@ -553,21 +551,16 @@ class nsIWidget : public nsISupports
     /**
      * Return the scaling factor between device pixels and the platform-
      * dependent "desktop pixels" used to manage window positions on a
      * potentially multi-screen, mixed-resolution desktop.
      */
     virtual mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() = 0;
 
     /**
-     * Returns the CompositorVsyncDispatcher associated with this widget
-     */
-    virtual CompositorVsyncDispatcher* GetCompositorVsyncDispatcher() = 0;
-
-    /**
      * Return the default scale factor for the window. This is the
      * default number of device pixels per CSS pixel to use. This should
      * depend on OS/platform settings such as the Mac's "UI scale factor"
      * or Windows' "font DPI". This will take into account Gecko preferences
      * overriding the system setting.
      */
     mozilla::CSSToLayoutDeviceScale GetDefaultScale();