diff --git a/widget/nsBaseWidget.cpp b/widget/nsBaseWidget.cpp index 124246dddcb7..0623e91f075e 100644 --- a/widget/nsBaseWidget.cpp +++ b/widget/nsBaseWidget.cpp @@ -43,6 +43,7 @@ #include "mozilla/MouseEvents.h" #include "GLConsts.h" #include "mozilla/unused.h" +#include "mozilla/VsyncDispatcher.h" #include "mozilla/layers/APZCTreeManager.h" #include "mozilla/layers/ChromeProcessController.h" @@ -111,6 +112,7 @@ nsBaseWidget::nsBaseWidget() : mWidgetListener(nullptr) , mAttachedWidgetListener(nullptr) , mContext(nullptr) +, mVsyncDispatcher(nullptr) , mCursor(eCursor_standard) , mUpdateCursor(true) , mBorderStyle(eBorderStyle_none) @@ -229,8 +231,12 @@ nsBaseWidget::~nsBaseWidget() NS_IF_RELEASE(mContext); delete mOriginalBounds; -} + // Can have base widgets that are things like tooltips which don't have vsyncDispatchers + if (mVsyncDispatcher) { + mVsyncDispatcher->Shutdown(); + } +} //------------------------------------------------------------------------- // @@ -944,6 +950,24 @@ nsBaseWidget::GetPreferredCompositorBackends(nsTArray& aHints) aHints.AppendElement(LayersBackend::LAYERS_BASIC); } +void nsBaseWidget::CreateVsyncDispatcher() +{ + if (gfxPrefs::HardwareVsyncEnabled()) { + // Parent directly listens to the vsync source whereas + // child process communicate via IPC + // Should be called AFTER gfxPlatform is initialized + if (XRE_IsParentProcess()) { + mVsyncDispatcher = new VsyncDispatcher(); + } + } +} + +VsyncDispatcher* +nsBaseWidget::GetVsyncDispatcher() +{ + return mVsyncDispatcher; +} + void nsBaseWidget::CreateCompositor(int aWidth, int aHeight) { // This makes sure that gfxPlatforms gets initialized if it hasn't by now. @@ -961,6 +985,7 @@ void nsBaseWidget::CreateCompositor(int aWidth, int aHeight) return; } + CreateVsyncDispatcher(); mCompositorParent = NewCompositorParent(aWidth, aHeight); MessageChannel *parentChannel = mCompositorParent->GetIPCChannel(); nsRefPtr lm = new ClientLayerManager(this); diff --git a/widget/nsBaseWidget.h b/widget/nsBaseWidget.h index 3a1cb6f4c52d..15bf254732c9 100644 --- a/widget/nsBaseWidget.h +++ b/widget/nsBaseWidget.h @@ -37,6 +37,8 @@ class CompositorParent; class APZCTreeManager; class GeckoContentController; } + +class VsyncDispatcher; } namespace base { @@ -138,6 +140,8 @@ public: LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT, bool* aAllowRetaining = nullptr); + VsyncDispatcher* GetVsyncDispatcher() MOZ_OVERRIDE; + virtual void CreateVsyncDispatcher(); virtual CompositorParent* NewCompositorParent(int aSurfaceWidth, int aSurfaceHeight); virtual void CreateCompositor(); virtual void CreateCompositor(int aWidth, int aHeight); @@ -414,6 +418,7 @@ protected: nsRefPtr mBasicLayerManager; nsRefPtr mCompositorChild; nsRefPtr mCompositorParent; + nsRefPtr mVsyncDispatcher; nsRefPtr mAPZC; nsRefPtr mShutdownObserver; nsCursor mCursor; diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index 14e44ee6221d..97f34cf52884 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -36,6 +36,7 @@ class nsIntRegion; class nsIScreen; namespace mozilla { +class VsyncDispatcher; namespace dom { class TabChild; } @@ -691,6 +692,7 @@ class nsIWidget : public nsISupports { typedef mozilla::widget::InputContext InputContext; typedef mozilla::widget::InputContextAction InputContextAction; typedef mozilla::widget::SizeConstraints SizeConstraints; + typedef mozilla::VsyncDispatcher VsyncDispatcher; // Used in UpdateThemeGeometries. struct ThemeGeometry { @@ -869,6 +871,11 @@ class nsIWidget : public nsISupports { */ virtual float GetDPI() = 0; + /** + * Returns the VsyncDispatcher associated with this widget + */ + virtual VsyncDispatcher* GetVsyncDispatcher() = 0; + /** * Return the default scale factor for the window. This is the * default number of device pixels per CSS pixel to use. This should