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 320504 a5086ab888367112761074071ce56ce95ca7a113
parent 320503 2872b9050cab51f33bc0d95b72461a990b80dd34
child 320505 ff82b00b481ed96257bd93ce3e28e882a2f292b6
push id9671
push userraliiev@mozilla.com
push dateMon, 06 Jun 2016 20:27:52 +0000
treeherdermozilla-aurora@cea65ca3d0bd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmchang
bugs1269037
milestone49.0a1
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();