Move CompositorWidget ownership from nsWindow to CompositorSession. (bug 1281998 part 4, r=jimm)
authorDavid Anderson <danderson@mozilla.com>
Fri, 01 Jul 2016 01:15:16 -0700
changeset 328449 1009ef8e1ed6abd37f210ea30b7c26f303f85fa3
parent 328448 887adb3d9482c267c5928f5d900252361f35ac25
child 328450 67eaf2f074bae7b04a751149767bfb8fd0a3988e
push id9858
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 14:37:10 +0000
treeherdermozilla-aurora@203106ef6cb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs1281998
milestone50.0a1
Move CompositorWidget ownership from nsWindow to CompositorSession. (bug 1281998 part 4, r=jimm)
gfx/ipc/CompositorSession.cpp
gfx/ipc/CompositorSession.h
gfx/ipc/GPUProcessManager.cpp
gfx/ipc/GPUProcessManager.h
widget/nsBaseWidget.cpp
widget/nsBaseWidget.h
widget/nsIWidget.h
widget/windows/nsWindow.cpp
--- a/gfx/ipc/CompositorSession.cpp
+++ b/gfx/ipc/CompositorSession.cpp
@@ -12,17 +12,17 @@ namespace mozilla {
 namespace layers {
 
 using namespace widget;
 
 class InProcessCompositorSession final : public CompositorSession
 {
 public:
   InProcessCompositorSession(
-    widget::CompositorWidget* aWidget,
+    nsIWidget* aWidget,
     ClientLayerManager* aLayerManager,
     CSSToLayoutDeviceScale aScale,
     bool aUseAPZ,
     bool aUseExternalSurfaceSize,
     const gfx::IntSize& aSurfaceSize);
 
   CompositorBridgeParent* GetInProcessBridge() const override;
   void SetContentController(GeckoContentController* aController) override;
@@ -30,17 +30,17 @@ public:
   already_AddRefed<APZCTreeManager> GetAPZCTreeManager() const override;
   void Shutdown() override;
 
 private:
   RefPtr<CompositorBridgeParent> mCompositorBridgeParent;
 };
 
 already_AddRefed<CompositorSession>
-CompositorSession::CreateInProcess(widget::CompositorWidget* aWidget,
+CompositorSession::CreateInProcess(nsIWidget* aWidget,
                                    ClientLayerManager* aLayerManager,
                                    CSSToLayoutDeviceScale aScale,
                                    bool aUseAPZ,
                                    bool aUseExternalSurfaceSize,
                                    const gfx::IntSize& aSurfaceSize)
 {
   RefPtr<InProcessCompositorSession> session = new InProcessCompositorSession(
     aWidget,
@@ -61,25 +61,26 @@ CompositorSession::~CompositorSession()
 }
 
 CompositorBridgeChild*
 CompositorSession::GetCompositorBridgeChild()
 {
   return mCompositorBridgeChild;
 }
 
-InProcessCompositorSession::InProcessCompositorSession(widget::CompositorWidget* aWidget,
+InProcessCompositorSession::InProcessCompositorSession(nsIWidget* aWidget,
                                                        ClientLayerManager* aLayerManager,
                                                        CSSToLayoutDeviceScale aScale,
                                                        bool aUseAPZ,
                                                        bool aUseExternalSurfaceSize,
                                                        const gfx::IntSize& aSurfaceSize)
 {
+  mCompositorWidget = aWidget->NewCompositorWidget();
   mCompositorBridgeParent = new CompositorBridgeParent(
-    aWidget,
+    mCompositorWidget,
     aScale,
     aUseAPZ,
     aUseExternalSurfaceSize,
     aSurfaceSize);
   mCompositorBridgeChild = new CompositorBridgeChild(aLayerManager);
   mCompositorBridgeChild->OpenSameProcess(mCompositorBridgeParent);
   mCompositorBridgeParent->SetOtherProcessId(base::GetCurrentProcId());
 }
@@ -113,12 +114,13 @@ InProcessCompositorSession::Shutdown()
 {
   // Destroy will synchronously wait for the parent to acknowledge shutdown,
   // at which point CBP will defer a Release on the compositor thread. We
   // can safely release our reference now, and let the destructor run on either
   // thread.
   mCompositorBridgeChild->Destroy();
   mCompositorBridgeChild = nullptr;
   mCompositorBridgeParent = nullptr;
+  mCompositorWidget = nullptr;
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/ipc/CompositorSession.h
+++ b/gfx/ipc/CompositorSession.h
@@ -6,16 +6,18 @@
 #ifndef _include_mozilla_gfx_ipc_CompositorSession_h_
 #define _include_mozilla_gfx_ipc_CompositorSession_h_
 
 #include "base/basictypes.h"
 #include "Units.h"
 #include "nsISupportsImpl.h"
 #include "mozilla/gfx/Point.h"
 
+class nsIWidget;
+
 namespace mozilla {
 namespace widget {
 class CompositorWidget;
 } // namespace widget
 namespace gfx {
 class GPUProcessManager;
 } // namespace gfx
 namespace layers {
@@ -27,16 +29,18 @@ 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;
 
+  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.
   virtual CompositorBridgeParent* GetInProcessBridge() const = 0;
 
@@ -47,30 +51,36 @@ public:
   virtual uint64_t RootLayerTreeId() const = 0;
 
   // Return the Async Pan/Zoom Tree Manager for this compositor.
   virtual already_AddRefed<APZCTreeManager> GetAPZCTreeManager() const = 0;
 
   // Return the child end of the compositor IPC bridge.
   CompositorBridgeChild* GetCompositorBridgeChild();
 
+  // Return the proxy for accessing the compositor's widget.
+  RefPtr<CompositorWidget> GetCompositorWidget() {
+    return mCompositorWidget;
+  }
+
 protected:
   CompositorSession();
   virtual ~CompositorSession();
 
   static already_AddRefed<CompositorSession> CreateInProcess(
-    widget::CompositorWidget* aWidget,
+    nsIWidget* aWidget,
     ClientLayerManager* aLayerManager,
     CSSToLayoutDeviceScale aScale,
     bool aUseAPZ,
     bool aUseExternalSurfaceSize,
     const gfx::IntSize& aSurfaceSize);
 
 protected:
   RefPtr<CompositorBridgeChild> mCompositorBridgeChild;
+  RefPtr<CompositorWidget> mCompositorWidget;
 
 private:
   DISALLOW_COPY_AND_ASSIGN(CompositorSession);
 };
 
 } // namespace layers
 } // namespace mozilla
 
--- a/gfx/ipc/GPUProcessManager.cpp
+++ b/gfx/ipc/GPUProcessManager.cpp
@@ -145,17 +145,17 @@ GPUProcessManager::DestroyProcess()
   }
 
   mProcess->Shutdown();
   mProcess = nullptr;
   mGPUChild = nullptr;
 }
 
 already_AddRefed<CompositorSession>
-GPUProcessManager::CreateTopLevelCompositor(widget::CompositorWidget* aWidget,
+GPUProcessManager::CreateTopLevelCompositor(nsIWidget* aWidget,
                                             ClientLayerManager* aLayerManager,
                                             CSSToLayoutDeviceScale aScale,
                                             bool aUseAPZ,
                                             bool aUseExternalSurfaceSize,
                                             const gfx::IntSize& aSurfaceSize)
 {
   return CompositorSession::CreateInProcess(
     aWidget,
--- a/gfx/ipc/GPUProcessManager.h
+++ b/gfx/ipc/GPUProcessManager.h
@@ -56,17 +56,17 @@ public:
   void EnableGPUProcess();
 
   // Ensure that GPU-bound methods can be used. If no GPU process is being
   // used, or one is launched and ready, this function returns immediately.
   // Otherwise it blocks until the GPU process has finished launching.
   void EnsureGPUReady();
 
   already_AddRefed<layers::CompositorSession> CreateTopLevelCompositor(
-    widget::CompositorWidget* aWidget,
+    nsIWidget* aWidget,
     layers::ClientLayerManager* aLayerManager,
     CSSToLayoutDeviceScale aScale,
     bool aUseAPZ,
     bool aUseExternalSurfaceSize,
     const gfx::IntSize& aSurfaceSize);
 
   layers::PCompositorBridgeParent* CreateTabCompositorBridge(
     ipc::Transport* aTransport,
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -269,26 +269,23 @@ void nsBaseWidget::DestroyCompositor()
   //  6. Step 5 will schedule DeferredDestroy on the compositor thread, which
   //     releases the reference CompositorBridgeParent holds to itself.
   //
   // When CompositorSession::Shutdown returns, we assume the compositor is gone
   // or will be gone very soon.
   if (mCompositorSession) {
     ReleaseContentController();
     mAPZC = nullptr;
+    mCompositorWidget = nullptr;
     mCompositorBridgeChild = nullptr;
 
     // XXX CompositorBridgeChild and CompositorBridgeParent might be re-created in
     // ClientLayerManager destructor. See bug 1133426.
     RefPtr<CompositorSession> session = mCompositorSession.forget();
     session->Shutdown();
-
-    // Widget is used in CompositorBridgeParent, so we can't release it until
-    // it has acknowledged shutdown.
-    mCompositorWidget = nullptr;
   }
 
   // Can have base widgets that are things like tooltips
   // which don't have CompositorVsyncDispatchers
   if (mCompositorVsyncDispatcher) {
     mCompositorVsyncDispatcher->Shutdown();
     mCompositorVsyncDispatcher = nullptr;
   }
@@ -1302,31 +1299,28 @@ void nsBaseWidget::CreateCompositor(int 
   // If we've already received a shutdown notification, don't try
   // create a new compositor.
   if (!mShutdownObserver) {
     return;
   }
 
   CreateCompositorVsyncDispatcher();
 
-  if (!mCompositorWidget) {
-    mCompositorWidget = NewCompositorWidget();
-  }
-
   RefPtr<ClientLayerManager> lm = new ClientLayerManager(this);
 
   gfx::GPUProcessManager* gpu = gfx::GPUProcessManager::Get();
   mCompositorSession = gpu->CreateTopLevelCompositor(
-    mCompositorWidget,
+    this,
     lm,
     GetDefaultScale(),
     UseAPZ(),
     UseExternalCompositingSurface(),
     gfx::IntSize(aWidth, aHeight));
   mCompositorBridgeChild = mCompositorSession->GetCompositorBridgeChild();
+  mCompositorWidget = mCompositorSession->GetCompositorWidget();
 
   mAPZC = mCompositorSession->GetAPZCTreeManager();
   if (mAPZC) {
     ConfigureAPZCTreeManager();
   }
 
   if (mInitialZoomConstraints) {
     UpdateZoomConstraints(mInitialZoomConstraints->mPresShellID,
--- a/widget/nsBaseWidget.h
+++ b/widget/nsBaseWidget.h
@@ -349,18 +349,17 @@ public:
   friend class AutoLayerManagerSetup;
 
   virtual bool            ShouldUseOffMainThreadCompositing();
 
   static nsIRollupListener* GetActiveRollupListener();
 
   void Shutdown();
 
-  // Return a new CompositorWidget for this widget.
-  virtual CompositorWidget* NewCompositorWidget();
+  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;
   }
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -60,16 +60,17 @@ struct ScrollableLayerGuid;
 } // namespace layers
 namespace gfx {
 class DrawTarget;
 class SourceSurface;
 } // namespace gfx
 namespace widget {
 class TextEventDispatcher;
 class TextEventDispatcherListener;
+class CompositorWidget;
 } // 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
@@ -1621,16 +1622,19 @@ 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;
+
 private:
   class LongTapInfo
   {
   public:
     LongTapInfo(int32_t aPointerId, LayoutDeviceIntPoint& aPoint,
                 mozilla::TimeDuration aDuration,
                 nsIObserver* aObserver) :
       mPointerId(aPointerId),
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -3612,23 +3612,25 @@ nsWindow::GetLayerManager(PLayerTransact
     // e10s uses the parameter to pass in the shadow manager from the TabChild
     // so we don't expect to see it there since this doesn't support e10s.
     NS_ASSERTION(aShadowManager == nullptr, "Async Compositor not supported with e10s");
     CreateCompositor();
   }
 
   if (!mLayerManager) {
     MOZ_ASSERT(!mCompositorSession && !mCompositorBridgeChild);
+    MOZ_ASSERT(!mCompositorWidget);
 
     // Ensure we have a widget proxy even if we're not using the compositor,
-    // since that's where we handle transparent windows.
-    if (!mCompositorWidget) {
-      mCompositorWidget= NewCompositorWidget();
-    }
-
+    // since all our transparent window handling lives there.
+    mCompositorWidget = new WinCompositorWidget(
+      mWnd,
+      reinterpret_cast<uintptr_t>(this),
+      mTransparencyMode,
+      this);
     mLayerManager = CreateBasicLayerManager();
   }
 
   NS_ASSERTION(mLayerManager, "Couldn't provide a valid layer manager.");
 
   return mLayerManager;
 }