Move CompositorWidget construction out of nsIWidget. (bug 1281998 part 5, r=jimm)
authorDavid Anderson <danderson@mozilla.com>
Fri, 01 Jul 2016 01:15:16 -0700
changeset 343416 67eaf2f074bae7b04a751149767bfb8fd0a3988e
parent 343415 1009ef8e1ed6abd37f210ea30b7c26f303f85fa3
child 343417 91f81099937fab0b1acf8a5cc930c7ceacd03488
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs1281998
milestone50.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
Move CompositorWidget construction out of nsIWidget. (bug 1281998 part 5, r=jimm)
gfx/ipc/CompositorSession.cpp
gfx/ipc/CompositorSession.h
widget/CompositorWidget.h
widget/InProcessCompositorWidget.cpp
widget/PlatformWidgetTypes.ipdlh
widget/PuppetWidget.h
widget/cocoa/nsCocoaWindow.h
widget/moz.build
widget/nsBaseWidget.cpp
widget/nsBaseWidget.h
widget/nsIWidget.h
widget/windows/PlatformWidgetTypes.ipdlh
widget/windows/WinCompositorWidget.cpp
widget/windows/WinCompositorWidget.h
widget/windows/nsWindow.cpp
widget/windows/nsWindow.h
--- a/gfx/ipc/CompositorSession.cpp
+++ b/gfx/ipc/CompositorSession.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=99: */
 /* 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 "CompositorSession.h"
 #include "mozilla/layers/CompositorBridgeChild.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
+#include "mozilla/widget/PlatformWidgetTypes.h"
 #include "base/process_util.h"
 
 namespace mozilla {
 namespace layers {
 
 using namespace widget;
 
 class InProcessCompositorSession final : public CompositorSession
@@ -68,17 +69,20 @@ CompositorSession::GetCompositorBridgeCh
 
 InProcessCompositorSession::InProcessCompositorSession(nsIWidget* aWidget,
                                                        ClientLayerManager* aLayerManager,
                                                        CSSToLayoutDeviceScale aScale,
                                                        bool aUseAPZ,
                                                        bool aUseExternalSurfaceSize,
                                                        const gfx::IntSize& aSurfaceSize)
 {
-  mCompositorWidget = aWidget->NewCompositorWidget();
+  CompositorWidgetInitData initData;
+  aWidget->GetCompositorWidgetInitData(&initData);
+  mCompositorWidget = CompositorWidget::CreateLocal(initData, aWidget);
+
   mCompositorBridgeParent = new CompositorBridgeParent(
     mCompositorWidget,
     aScale,
     aUseAPZ,
     aUseExternalSurfaceSize,
     aSurfaceSize);
   mCompositorBridgeChild = new CompositorBridgeChild(aLayerManager);
   mCompositorBridgeChild->OpenSameProcess(mCompositorBridgeParent);
--- a/gfx/ipc/CompositorSession.h
+++ b/gfx/ipc/CompositorSession.h
@@ -29,16 +29,17 @@ class CompositorBridgeChild;
 class ClientLayerManager;
 
 // A CompositorSession provides access to a compositor without exposing whether
 // or not it's in-process or out-of-process.
 class CompositorSession
 {
   friend class gfx::GPUProcessManager;
 
+protected:
   typedef widget::CompositorWidget CompositorWidget;
 
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorSession)
 
   virtual void Shutdown() = 0;
 
   // This returns a CompositorBridgeParent if the compositor resides in the same process.
--- a/widget/CompositorWidget.h
+++ b/widget/CompositorWidget.h
@@ -24,26 +24,33 @@ class Composer2D;
 } // namespace layers
 namespace gfx {
 class DrawTarget;
 class SourceSurface;
 } // namespace gfx
 namespace widget {
 
 class WinCompositorWidget;
+class CompositorWidgetInitData;
 
 /**
  * Access to a widget from the compositor is restricted to these methods.
  */
 class CompositorWidget
 {
 public:
   NS_INLINE_DECL_REFCOUNTING(mozilla::widget::CompositorWidget)
 
   /**
+   * Create an in-process compositor widget. aWidget may be ignored if the
+   * platform does not require it.
+   */
+  static RefPtr<CompositorWidget> CreateLocal(const CompositorWidgetInitData& aInitData, nsIWidget* aWidget);
+
+  /**
    * Called before rendering using OMTC. Returns false when the widget is
    * not ready to be rendered (for example while the window is closed).
    *
    * Always called from the compositing thread, which may be the main-thread if
    * OMTC is not enabled.
    */
   virtual bool PreRender(layers::LayerManagerComposite* aManager) {
     return true;
--- a/widget/InProcessCompositorWidget.cpp
+++ b/widget/InProcessCompositorWidget.cpp
@@ -1,17 +1,29 @@
 /* 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 "InProcessCompositorWidget.h"
+#include "nsBaseWidget.h"
 
 namespace mozilla {
 namespace widget {
 
+// Platforms with no OOP compositor process support use
+// InProcessCompositorWidget by default.
+#if !defined(XP_WIN)
+/* static */ RefPtr<CompositorWidget>
+CompositorWidget::CreateLocal(const CompositorWidgetInitData& aInitData, nsIWidget* aWidget)
+{
+  MOZ_ASSERT(aWidget);
+  return new InProcessCompositorWidget(static_cast<nsBaseWidget*>(aWidget));
+}
+#endif
+
 InProcessCompositorWidget::InProcessCompositorWidget(nsBaseWidget* aWidget)
  : mWidget(aWidget)
 {
 }
 
 bool
 InProcessCompositorWidget::PreRender(layers::LayerManagerComposite* aManager)
 {
new file mode 100644
--- /dev/null
+++ b/widget/PlatformWidgetTypes.ipdlh
@@ -0,0 +1,18 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=99: */
+/* 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/. */
+
+// This file is a stub, for platforms that do not yet support out-of-process
+// compositing or do not need specialized types to do so.
+
+namespace mozilla {
+namespace widget {
+
+struct CompositorWidgetInitData
+{
+};
+
+} // namespace widget
+} // namespace mozilla
--- a/widget/PuppetWidget.h
+++ b/widget/PuppetWidget.h
@@ -274,22 +274,16 @@ public:
                  const nsTArray<mozilla::FontRange>& aFontRangeArray,
                  const bool aIsVertical,
                  const LayoutDeviceIntPoint& aPoint) override;
 
 protected:
   virtual nsresult NotifyIMEInternal(
                      const IMENotification& aIMENotification) override;
 
-  // PuppetWidgets do not create compositors.
-  widget::CompositorWidget* NewCompositorWidget() override {
-    MOZ_ASSERT_UNREACHABLE("PuppetWidgets should not have widget proxies");
-    return nullptr;
-  }
-
 private:
   nsresult Paint();
 
   void SetChild(PuppetWidget* aChild);
 
   nsresult RequestIMEToCommitComposition(bool aCancel);
   nsresult NotifyIMEOfFocusChange(const IMENotification& aIMENotification);
   nsresult NotifyIMEOfSelectionChange(const IMENotification& aIMENotification);
--- a/widget/cocoa/nsCocoaWindow.h
+++ b/widget/cocoa/nsCocoaWindow.h
@@ -348,20 +348,16 @@ public:
                         const mozilla::WidgetKeyboardEvent& aEvent,
                         DoCommandCallback aCallback,
                         void* aCallbackData) override;
 
     void SetPopupWindowLevel();
 
     NS_IMETHOD         ReparentNativeWidget(nsIWidget* aNewParent) override;
 
-    CompositorWidget* NewCompositorWidget() override {
-      return nullptr;
-    }
-
 protected:
   virtual ~nsCocoaWindow();
 
   nsresult             CreateNativeWindow(const NSRect &aRect,
                                           nsBorderStyle aBorderStyle,
                                           bool aRectIsFrameRect);
   nsresult             CreatePopupContentView(const LayoutDeviceIntRect &aRect);
   void                 DestroyNativeWindow();
--- a/widget/moz.build
+++ b/widget/moz.build
@@ -237,16 +237,25 @@ LOCAL_INCLUDES += [
     '/layout/base',
     '/layout/forms',
     '/layout/generic',
     '/layout/xul',
     '/view',
     '/widget',
 ]
 
+if toolkit == 'windows':
+    IPDL_SOURCES = [
+        'windows/PlatformWidgetTypes.ipdlh',
+    ]
+else:
+    IPDL_SOURCES = [
+        'PlatformWidgetTypes.ipdlh',
+    ]
+
 widget_dir = toolkit
 if widget_dir in ('gtk3', 'gtk2'):
     # gtk3 shares includes with gtk2
     widget_dir = 'gtk'
 
 LOCAL_INCLUDES += [
     '/widget/%s' % widget_dir,
 ]
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -67,17 +67,16 @@
 #include "WritingModes.h"
 #include "InputData.h"
 #include "FrameLayerBuilder.h"
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 #include "gfxConfig.h"
 #include "mozilla/layers/CompositorSession.h"
-#include "InProcessCompositorWidget.h"
 
 #ifdef DEBUG
 #include "nsIObserver.h"
 
 static void debug_RegisterPrefCallbacks();
 
 #endif
 
@@ -1410,22 +1409,16 @@ nsBaseWidget::StartRemoteDrawing()
 }
 
 uint32_t
 nsBaseWidget::GetGLFrameBufferFormat()
 {
   return LOCAL_GL_RGBA;
 }
 
-mozilla::widget::CompositorWidget*
-nsBaseWidget::NewCompositorWidget()
-{
-  return new mozilla::widget::InProcessCompositorWidget(this);
-}
-
 //-------------------------------------------------------------------------
 //
 // Destroy the window
 //
 //-------------------------------------------------------------------------
 void nsBaseWidget::OnDestroy()
 {
   if (mTextEventDispatcher) {
--- a/widget/nsBaseWidget.h
+++ b/widget/nsBaseWidget.h
@@ -349,18 +349,16 @@ public:
   friend class AutoLayerManagerSetup;
 
   virtual bool            ShouldUseOffMainThreadCompositing();
 
   static nsIRollupListener* GetActiveRollupListener();
 
   void Shutdown();
 
-  virtual mozilla::widget::CompositorWidget* NewCompositorWidget() override;
-
 protected:
   // These are methods for CompositorWidgetWrapper, and should only be
   // accessed from that class. Derived widgets can choose which methods to
   // implement, or none if supporting out-of-process compositing.
   virtual bool PreRender(mozilla::layers::LayerManagerComposite* aManager) {
     return true;
   }
   virtual void PostRender(mozilla::layers::LayerManagerComposite* aManager)
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -61,16 +61,17 @@ struct ScrollableLayerGuid;
 namespace gfx {
 class DrawTarget;
 class SourceSurface;
 } // namespace gfx
 namespace widget {
 class TextEventDispatcher;
 class TextEventDispatcherListener;
 class CompositorWidget;
+class CompositorWidgetInitData;
 } // namespace widget
 } // namespace mozilla
 
 /**
  * Callback function that processes events.
  *
  * The argument is actually a subtype (subclass) of WidgetEvent which carries
  * platform specific information about the event. Platform specific code
@@ -1622,18 +1623,20 @@ class nsIWidget : public nsISupports
      * digitizer state when this call is made.
      * @param aObserver The observer that will get notified once the touch
      * sequence has been cleared.
      */
     virtual nsresult ClearNativeTouchSequence(nsIObserver* aObserver);
 
     virtual void StartAsyncScrollbarDrag(const AsyncDragMetrics& aDragMetrics) = 0;
 
-    // Return a new CompositorWidget for this widget.
-    virtual mozilla::widget::CompositorWidget* NewCompositorWidget() = 0;
+    // If this widget supports out-of-process compositing, it can override
+    // this method to provide additional information to the compositor.
+    virtual void GetCompositorWidgetInitData(mozilla::widget::CompositorWidgetInitData* aInitData)
+    {}
 
 private:
   class LongTapInfo
   {
   public:
     LongTapInfo(int32_t aPointerId, LayoutDeviceIntPoint& aPoint,
                 mozilla::TimeDuration aDuration,
                 nsIObserver* aObserver) :
new file mode 100644
--- /dev/null
+++ b/widget/windows/PlatformWidgetTypes.ipdlh
@@ -0,0 +1,23 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=99: */
+/* 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/. */
+
+// This file is a stub, for platforms that do not yet support out-of-process
+// compositing or do not need specialized types to do so.
+
+using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h";
+
+namespace mozilla {
+namespace widget {
+
+struct CompositorWidgetInitData
+{
+  WindowsHandle hWnd;
+  uintptr_t widgetKey;
+  int32_t transparencyMode;
+};
+
+} // namespace widget
+} // namespace mozilla
--- a/widget/windows/WinCompositorWidget.cpp
+++ b/widget/windows/WinCompositorWidget.cpp
@@ -2,30 +2,35 @@
 /* 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 "WinCompositorWidget.h"
 #include "nsWindow.h"
 #include "VsyncDispatcher.h"
 #include "mozilla/gfx/Point.h"
+#include "mozilla/widget/PlatformWidgetTypes.h"
 
 namespace mozilla {
 namespace widget {
 
 using namespace mozilla::gfx;
 
-WinCompositorWidget::WinCompositorWidget(HWND aWnd,
-                                         uintptr_t aWidgetKey,
-                                         nsTransparencyMode aMode,
+/* static */ RefPtr<CompositorWidget>
+CompositorWidget::CreateLocal(const CompositorWidgetInitData& aInitData, nsIWidget* aWidget)
+{
+  return new WinCompositorWidget(aInitData, static_cast<nsWindow*>(aWidget));
+}
+
+WinCompositorWidget::WinCompositorWidget(const CompositorWidgetInitData& aInitData,
                                          nsWindow* aWindow)
  : mWindow(aWindow),
-   mWidgetKey(aWidgetKey),
-   mWnd(aWnd),
-   mTransparencyMode(aMode),
+   mWidgetKey(aInitData.widgetKey()),
+   mWnd(reinterpret_cast<HWND>(aInitData.hWnd())),
+   mTransparencyMode(static_cast<nsTransparencyMode>(aInitData.transparencyMode())),
    mMemoryDC(nullptr),
    mCompositeDC(nullptr),
    mLockedBackBufferData(nullptr)
 {
   MOZ_ASSERT(mWnd && ::IsWindow(mWnd));
 }
 
 void
--- a/widget/windows/WinCompositorWidget.h
+++ b/widget/windows/WinCompositorWidget.h
@@ -16,19 +16,17 @@ namespace widget {
  
 // This is the Windows-specific implementation of CompositorWidget. For
 // the most part it only requires an HWND, however it maintains extra state
 // for transparent windows, as well as for synchronizing WM_SETTEXT messages
 // with the compositor.
 class WinCompositorWidget: public CompositorWidget
 {
 public:
-  WinCompositorWidget(HWND aWnd,
-                      uintptr_t aWidgetKey,
-                      nsTransparencyMode aMode,
+  WinCompositorWidget(const CompositorWidgetInitData& aInitData,
                       nsWindow* aWindow = nullptr);
 
   bool PreRender(layers::LayerManagerComposite*) override;
   void PostRender(layers::LayerManagerComposite*) override;
   already_AddRefed<gfx::DrawTarget> StartRemoteDrawing() override;
   void EndRemoteDrawing() override;
   LayoutDeviceIntSize GetClientSize() override;
   already_AddRefed<gfx::DrawTarget> GetBackBufferDrawTarget(gfx::DrawTarget* aScreenTarget,
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -131,16 +131,17 @@
 #include "mozilla/dom/Touch.h"
 #include "mozilla/gfx/2D.h"
 #include "nsToolkitCompsCID.h"
 #include "nsIAppStartup.h"
 #include "mozilla/WindowsVersion.h"
 #include "mozilla/TextEvents.h" // For WidgetKeyboardEvent
 #include "mozilla/TextEventDispatcherListener.h"
 #include "mozilla/widget/WinNativeEventData.h"
+#include "mozilla/widget/PlatformWidgetTypes.h"
 #include "nsThemeConstants.h"
 #include "nsBidiKeyboard.h"
 #include "nsThemeConstants.h"
 #include "gfxConfig.h"
 #include "WinCompositorWidget.h"
 
 #include "nsIGfxInfo.h"
 #include "nsUXThemeConstants.h"
@@ -3616,21 +3617,21 @@ nsWindow::GetLayerManager(PLayerTransact
   }
 
   if (!mLayerManager) {
     MOZ_ASSERT(!mCompositorSession && !mCompositorBridgeChild);
     MOZ_ASSERT(!mCompositorWidget);
 
     // Ensure we have a widget proxy even if we're not using the compositor,
     // since all our transparent window handling lives there.
-    mCompositorWidget = new WinCompositorWidget(
-      mWnd,
-      reinterpret_cast<uintptr_t>(this),
-      mTransparencyMode,
-      this);
+    CompositorWidgetInitData initData(
+      reinterpret_cast<uintptr_t>(mWnd),
+      reinterpret_cast<uintptr_t>(static_cast<nsIWidget*>(this)),
+      mTransparencyMode);
+    mCompositorWidget = new WinCompositorWidget(initData, this);
     mLayerManager = CreateBasicLayerManager();
   }
 
   NS_ASSERTION(mLayerManager, "Couldn't provide a valid layer manager.");
 
   return mLayerManager;
 }
 
@@ -3681,26 +3682,16 @@ nsWindow::OnDefaultButtonLoaded(const La
 
   if (!::SetCursorPos(centerOfButton.x, centerOfButton.y)) {
     NS_ERROR("SetCursorPos failed");
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
-mozilla::widget::CompositorWidget*
-nsWindow::NewCompositorWidget()
-{
-  return new WinCompositorWidget(
-    mWnd,
-    reinterpret_cast<uintptr_t>(this),
-    mTransparencyMode,
-    this);
-}
-
 mozilla::widget::WinCompositorWidget*
 nsWindow::GetCompositorWidget()
 {
   return mCompositorWidget? mCompositorWidget->AsWindows() : nullptr;
 }
 
 void
 nsWindow::UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries)
@@ -7820,8 +7811,16 @@ nsWindow::OnWindowedPluginKeyEvent(const
 DWORD ChildWindow::WindowStyle()
 {
   DWORD style = WS_CLIPCHILDREN | nsWindow::WindowStyle();
   if (!(style & WS_POPUP))
     style |= WS_CHILD; // WS_POPUP and WS_CHILD are mutually exclusive.
   VERIFY_WINDOW_STYLE(style);
   return style;
 }
+
+void
+nsWindow::GetCompositorWidgetInitData(mozilla::widget::CompositorWidgetInitData* aInitData)
+{
+  aInitData->hWnd() = reinterpret_cast<uintptr_t>(mWnd);
+  aInitData->widgetKey() = reinterpret_cast<uintptr_t>(static_cast<nsIWidget*>(this));
+  aInitData->transparencyMode() = mTransparencyMode;
+}
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -307,17 +307,17 @@ public:
                  const mozilla::widget::CandidateWindowPosition&
                    aPosition) override;
   virtual void DefaultProcOfPluginEvent(
                  const mozilla::WidgetPluginEvent& aEvent) override;
   virtual nsresult OnWindowedPluginKeyEvent(
                      const mozilla::NativeEventData& aKeyEventData,
                      nsIKeyEventInPluginCallback* aCallback) override;
 
-  mozilla::widget::CompositorWidget* NewCompositorWidget() override;
+  void GetCompositorWidgetInitData(mozilla::widget::CompositorWidgetInitData* aInitData) override;
 
 protected:
   virtual ~nsWindow();
 
   virtual void WindowUsesOMTC() override;
   virtual void RegisterTouchWindow() override;
 
   // A magic number to identify the FAKETRACKPOINTSCROLLABLE window created