Move CompositorWidget construction out of nsIWidget. (bug 1281998 part 5, r=jimm)
☠☠ backed out by 48bd14a01b55 ☠ ☠
authorDavid Anderson <danderson@mozilla.com>
Wed, 29 Jun 2016 16:47:22 -0400
changeset 303200 a72929c0c3ec750dfb3127f51f54cbb2432d1a9d
parent 303199 74198f88fa3715d5f7a01b7186af341a540614b6
child 303201 b8d4fedfd7eb7354b34521b161d430cda684848f
push id19824
push usercbook@mozilla.com
push dateThu, 30 Jun 2016 10:53:06 +0000
treeherderfx-team@7b4e8a8e4f0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs1281998
milestone50.0a1
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
@@ -275,22 +275,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
@@ -349,20 +349,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
 
@@ -1414,22 +1413,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
@@ -350,18 +350,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
@@ -1627,18 +1628,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"
@@ -3621,21 +3622,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;
 }
 
@@ -3686,26 +3687,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)
@@ -7825,8 +7816,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
@@ -308,17 +308,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