Extract a delegate interface out of WinCompositorWidget. (bug 1281998 part 6, r=jimm)
☠☠ backed out by 48bd14a01b55 ☠ ☠
authorDavid Anderson <danderson@mozilla.com>
Wed, 29 Jun 2016 16:47:23 -0400
changeset 345300 b8d4fedfd7eb7354b34521b161d430cda684848f
parent 345299 a72929c0c3ec750dfb3127f51f54cbb2432d1a9d
child 345301 d806fac2c856f7c7f08049eb0eefbabba7283939
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [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
Extract a delegate interface out of WinCompositorWidget. (bug 1281998 part 6, r=jimm)
gfx/ipc/CompositorSession.cpp
gfx/ipc/CompositorSession.h
widget/CompositorWidget.h
widget/nsBaseWidget.cpp
widget/nsBaseWidget.h
widget/windows/WinCompositorWidget.cpp
widget/windows/WinCompositorWidget.h
widget/windows/nsWindow.cpp
widget/windows/nsWindow.h
widget/windows/nsWindowGfx.cpp
--- a/gfx/ipc/CompositorSession.cpp
+++ b/gfx/ipc/CompositorSession.cpp
@@ -28,16 +28,17 @@ public:
   CompositorBridgeParent* GetInProcessBridge() const override;
   void SetContentController(GeckoContentController* aController) override;
   uint64_t RootLayerTreeId() const override;
   already_AddRefed<APZCTreeManager> GetAPZCTreeManager() const override;
   void Shutdown() override;
 
 private:
   RefPtr<CompositorBridgeParent> mCompositorBridgeParent;
+  RefPtr<CompositorWidget> mCompositorWidget;
 };
 
 already_AddRefed<CompositorSession>
 CompositorSession::CreateInProcess(nsIWidget* aWidget,
                                    ClientLayerManager* aLayerManager,
                                    CSSToLayoutDeviceScale aScale,
                                    bool aUseAPZ,
                                    bool aUseExternalSurfaceSize,
@@ -49,16 +50,17 @@ CompositorSession::CreateInProcess(nsIWi
     aScale,
     aUseAPZ,
     aUseExternalSurfaceSize,
     aSurfaceSize);
   return session.forget();
 }
 
 CompositorSession::CompositorSession()
+ : mCompositorWidgetDelegate(nullptr)
 {
 }
 
 CompositorSession::~CompositorSession()
 {
 }
 
 CompositorBridgeChild*
@@ -72,16 +74,17 @@ InProcessCompositorSession::InProcessCom
                                                        CSSToLayoutDeviceScale aScale,
                                                        bool aUseAPZ,
                                                        bool aUseExternalSurfaceSize,
                                                        const gfx::IntSize& aSurfaceSize)
 {
   CompositorWidgetInitData initData;
   aWidget->GetCompositorWidgetInitData(&initData);
   mCompositorWidget = CompositorWidget::CreateLocal(initData, aWidget);
+  mCompositorWidgetDelegate = mCompositorWidget->AsDelegate();
 
   mCompositorBridgeParent = new CompositorBridgeParent(
     mCompositorWidget,
     aScale,
     aUseAPZ,
     aUseExternalSurfaceSize,
     aSurfaceSize);
   mCompositorBridgeChild = new CompositorBridgeChild(aLayerManager);
--- a/gfx/ipc/CompositorSession.h
+++ b/gfx/ipc/CompositorSession.h
@@ -11,16 +11,17 @@
 #include "nsISupportsImpl.h"
 #include "mozilla/gfx/Point.h"
 
 class nsIWidget;
 
 namespace mozilla {
 namespace widget {
 class CompositorWidget;
+class CompositorWidgetDelegate;
 } // namespace widget
 namespace gfx {
 class GPUProcessManager;
 } // namespace gfx
 namespace layers {
 
 class GeckoContentController;
 class APZCTreeManager;
@@ -31,16 +32,17 @@ 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;
+  typedef widget::CompositorWidgetDelegate CompositorWidgetDelegate;
 
 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;
@@ -53,35 +55,35 @@ public:
 
   // 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;
+  CompositorWidgetDelegate* GetCompositorWidgetDelegate() {
+    return mCompositorWidgetDelegate;
   }
 
 protected:
   CompositorSession();
   virtual ~CompositorSession();
 
   static already_AddRefed<CompositorSession> CreateInProcess(
     nsIWidget* aWidget,
     ClientLayerManager* aLayerManager,
     CSSToLayoutDeviceScale aScale,
     bool aUseAPZ,
     bool aUseExternalSurfaceSize,
     const gfx::IntSize& aSurfaceSize);
 
 protected:
   RefPtr<CompositorBridgeChild> mCompositorBridgeChild;
-  RefPtr<CompositorWidget> mCompositorWidget;
+  CompositorWidgetDelegate* mCompositorWidgetDelegate;
 
 private:
   DISALLOW_COPY_AND_ASSIGN(CompositorSession);
 };
 
 } // namespace layers
 } // namespace mozilla
 
--- a/widget/CompositorWidget.h
+++ b/widget/CompositorWidget.h
@@ -26,16 +26,23 @@ namespace gfx {
 class DrawTarget;
 class SourceSurface;
 } // namespace gfx
 namespace widget {
 
 class WinCompositorWidget;
 class CompositorWidgetInitData;
 
+// Gecko widgets usually need to communicate with the CompositorWidget with
+// platform-specific messages (for example to update the window size or
+// transparency). This functionality is controlled through a "host". Since
+// this functionality is platform-dependent, it is only forward declared
+// here.
+class CompositorWidgetDelegate;
+
 /**
  * Access to a widget from the compositor is restricted to these methods.
  */
 class CompositorWidget
 {
 public:
   NS_INLINE_DECL_REFCOUNTING(mozilla::widget::CompositorWidget)
 
@@ -206,16 +213,23 @@ public:
    * Return a compositor vsync dispatcher for this widget.
    */
   virtual already_AddRefed<CompositorVsyncDispatcher> GetCompositorVsyncDispatcher() = 0;
 
   virtual WinCompositorWidget* AsWindows() {
     return nullptr;
   }
 
+  /**
+   * Return the platform-specific delegate for the widget, if any.
+   */
+  virtual CompositorWidgetDelegate* AsDelegate() {
+    return nullptr;
+  }
+
 protected:
   virtual ~CompositorWidget();
 
   // Back buffer of BasicCompositor
   RefPtr<gfx::DrawTarget> mLastBackBuffer;
 };
 
 } // namespace widget
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -166,16 +166,17 @@ nsBaseWidget::nsBaseWidget()
 , mCursor(eCursor_standard)
 , mBorderStyle(eBorderStyle_none)
 , mBounds(0,0,0,0)
 , mOriginalBounds(nullptr)
 , mClipRectCount(0)
 , mSizeMode(nsSizeMode_Normal)
 , mPopupLevel(ePopupLevelTop)
 , mPopupType(ePopupTypeAny)
+, mCompositorWidgetDelegate(nullptr)
 , mUpdateCursor(true)
 , mUseAttachedEvents(false)
 , mIMEHasFocus(false)
 #if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_GTK)
 , mAccessibilityInUseFlag(false)
 #endif
 {
 #ifdef NOISY_WIDGET_LEAKS
@@ -268,17 +269,17 @@ 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;
+    mCompositorWidgetDelegate = nullptr;
     mCompositorBridgeChild = nullptr;
 
     // XXX CompositorBridgeChild and CompositorBridgeParent might be re-created in
     // ClientLayerManager destructor. See bug 1133426.
     RefPtr<CompositorSession> session = mCompositorSession.forget();
     session->Shutdown();
   }
 
@@ -1309,17 +1310,17 @@ void nsBaseWidget::CreateCompositor(int 
   mCompositorSession = gpu->CreateTopLevelCompositor(
     this,
     lm,
     GetDefaultScale(),
     UseAPZ(),
     UseExternalCompositingSurface(),
     gfx::IntSize(aWidth, aHeight));
   mCompositorBridgeChild = mCompositorSession->GetCompositorBridgeChild();
-  mCompositorWidget = mCompositorSession->GetCompositorWidget();
+  mCompositorWidgetDelegate = mCompositorSession->GetCompositorWidgetDelegate();
 
   mAPZC = mCompositorSession->GetAPZCTreeManager();
   if (mAPZC) {
     ConfigureAPZCTreeManager();
   }
 
   if (mInitialZoomConstraints) {
     UpdateZoomConstraints(mInitialZoomConstraints->mPresShellID,
--- a/widget/nsBaseWidget.h
+++ b/widget/nsBaseWidget.h
@@ -45,17 +45,17 @@ class CompositorBridgeParent;
 class APZCTreeManager;
 class GeckoContentController;
 class APZEventState;
 class CompositorSession;
 struct ScrollableLayerGuid;
 } // namespace layers
 
 namespace widget {
-class CompositorWidget;
+class CompositorWidgetDelegate;
 class InProcessCompositorWidget;
 } // namespace widget
 
 class CompositorVsyncDispatcher;
 } // namespace mozilla
 
 namespace base {
 class Thread;
@@ -111,17 +111,17 @@ protected:
   typedef mozilla::layers::APZCTreeManager APZCTreeManager;
   typedef mozilla::layers::GeckoContentController GeckoContentController;
   typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
   typedef mozilla::layers::APZEventState APZEventState;
   typedef mozilla::layers::SetAllowedTouchBehaviorCallback SetAllowedTouchBehaviorCallback;
   typedef mozilla::CSSIntRect CSSIntRect;
   typedef mozilla::CSSRect CSSRect;
   typedef mozilla::ScreenRotation ScreenRotation;
-  typedef mozilla::widget::CompositorWidget CompositorWidget;
+  typedef mozilla::widget::CompositorWidgetDelegate CompositorWidgetDelegate;
   typedef mozilla::layers::CompositorSession CompositorSession;
 
   virtual ~nsBaseWidget();
 
 public:
   nsBaseWidget();
 
   NS_DECL_ISUPPORTS
@@ -584,17 +584,17 @@ protected:
   // When this pointer is null, the widget is not clipped
   mozilla::UniquePtr<LayoutDeviceIntRect[]> mClipRects;
   uint32_t          mClipRectCount;
   nsSizeMode        mSizeMode;
   nsPopupLevel      mPopupLevel;
   nsPopupType       mPopupType;
   SizeConstraints   mSizeConstraints;
 
-  RefPtr<CompositorWidget> mCompositorWidget;
+  CompositorWidgetDelegate* mCompositorWidgetDelegate;
 
   bool              mUpdateCursor;
   bool              mUseAttachedEvents;
   bool              mIMEHasFocus;
 #if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_GTK)
   bool              mAccessibilityInUseFlag;
 #endif
   static nsIRollupListener* gRollupListener;
--- a/widget/windows/WinCompositorWidget.cpp
+++ b/widget/windows/WinCompositorWidget.cpp
@@ -200,29 +200,28 @@ WinCompositorWidget::LeavePresentLock()
 
 RefPtr<gfxASurface>
 WinCompositorWidget::EnsureTransparentSurface()
 {
   MOZ_ASSERT(mTransparencyMode == eTransparencyTransparent);
 
   if (!mTransparentSurface) {
     LayoutDeviceIntSize size = GetClientSize();
-    CreateTransparentSurface(size.width, size.height);
+    CreateTransparentSurface(IntSize(size.width, size.height));
   }
 
   RefPtr<gfxASurface> surface = mTransparentSurface;
   return surface.forget();
 }
 
 void
-WinCompositorWidget::CreateTransparentSurface(int32_t aWidth, int32_t aHeight)
+WinCompositorWidget::CreateTransparentSurface(const gfx::IntSize& aSize)
 {
   MOZ_ASSERT(!mTransparentSurface && !mMemoryDC);
-  RefPtr<gfxWindowsSurface> surface =
-    new gfxWindowsSurface(IntSize(aWidth, aHeight), SurfaceFormat::A8R8G8B8_UINT32);
+  RefPtr<gfxWindowsSurface> surface = new gfxWindowsSurface(aSize, SurfaceFormat::A8R8G8B8_UINT32);
   mTransparentSurface = surface;
   mMemoryDC = surface->GetDC();
 }
 
 void
 WinCompositorWidget::UpdateTransparency(nsTransparencyMode aMode)
 {
   if (mTransparencyMode == aMode) {
@@ -248,31 +247,29 @@ WinCompositorWidget::ClearTransparentWin
   IntSize size = mTransparentSurface->GetSize();
   RefPtr<DrawTarget> drawTarget = gfxPlatform::GetPlatform()->
     CreateDrawTargetForSurface(mTransparentSurface, size);
   drawTarget->ClearRect(Rect(0, 0, size.width, size.height));
   RedrawTransparentWindow();
 }
 
 void
-WinCompositorWidget::ResizeTransparentWindow(int32_t aNewWidth, int32_t aNewHeight)
+WinCompositorWidget::ResizeTransparentWindow(const gfx::IntSize& aSize)
 {
   MOZ_ASSERT(mTransparencyMode == eTransparencyTransparent);
 
-  if (mTransparentSurface &&
-      mTransparentSurface->GetSize() == IntSize(aNewWidth, aNewHeight))
-  {
+  if (mTransparentSurface && mTransparentSurface->GetSize() == aSize) {
     return;
   }
 
   // Destroy the old surface.
   mTransparentSurface = nullptr;
   mMemoryDC = nullptr;
 
-  CreateTransparentSurface(aNewWidth, aNewHeight);
+  CreateTransparentSurface(aSize);
 }
 
 bool
 WinCompositorWidget::RedrawTransparentWindow()
 {
   MOZ_ASSERT(mTransparencyMode == eTransparencyTransparent);
 
   LayoutDeviceIntSize size = GetClientSize();
--- a/widget/windows/WinCompositorWidget.h
+++ b/widget/windows/WinCompositorWidget.h
@@ -3,27 +3,50 @@
  * 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/. */
 
 #ifndef _widget_windows_WinCompositorWidget_h__
 #define _widget_windows_WinCompositorWidget_h__
 
 #include "CompositorWidget.h"
 #include "mozilla/gfx/CriticalSection.h"
+#include "mozilla/gfx/Point.h"
 
 class nsWindow;
 
 namespace mozilla {
 namespace widget {
+
+class CompositorWidgetDelegate
+{
+public:
+  // Callbacks for nsWindow.
+  virtual void EnterPresentLock() = 0;
+  virtual void LeavePresentLock() = 0;
+  virtual void OnDestroyWindow() = 0;
+
+  // Transparency handling.
+  virtual void UpdateTransparency(nsTransparencyMode aMode) = 0;
+  virtual void ClearTransparentWindow() = 0;
+
+  // Update the bounds of the transparent surface.
+  virtual void ResizeTransparentWindow(const gfx::IntSize& aSize) = 0;
+
+  // If in-process and using software rendering, return the backing transparent
+  // DC.
+  virtual HDC GetTransparentDC() const = 0;
+};
  
 // 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
+class WinCompositorWidget
+ : public CompositorWidget,
+   public CompositorWidgetDelegate
 {
 public:
   WinCompositorWidget(const CompositorWidgetInitData& aInitData,
                       nsWindow* aWindow = nullptr);
 
   bool PreRender(layers::LayerManagerComposite*) override;
   void PostRender(layers::LayerManagerComposite*) override;
   already_AddRefed<gfx::DrawTarget> StartRemoteDrawing() override;
@@ -35,44 +58,41 @@ public:
   already_AddRefed<gfx::SourceSurface> EndBackBufferDrawing() override;
   already_AddRefed<CompositorVsyncDispatcher> GetCompositorVsyncDispatcher() override;
   uintptr_t GetWidgetKey() override;
   nsIWidget* RealWidget() override;
   WinCompositorWidget* AsWindows() override {
     return this;
   }
 
-  // Callbacks for nsWindow.
-  void EnterPresentLock();
-  void LeavePresentLock();
-  void OnDestroyWindow();
+  // CompositorWidgetDelegate overrides.
+  void EnterPresentLock() override;
+  void LeavePresentLock() override;
+  void OnDestroyWindow() override;
+  void UpdateTransparency(nsTransparencyMode aMode) override;
+  void ClearTransparentWindow() override;
+  void ResizeTransparentWindow(const gfx::IntSize& aSize) override;
 
-  // Transparency handling.
-  void UpdateTransparency(nsTransparencyMode aMode);
-  void ClearTransparentWindow();
   bool RedrawTransparentWindow();
 
-  // Update the bounds of the transparent surface.
-  void ResizeTransparentWindow(int32_t aNewWidth, int32_t aNewHeight);
-
   // Ensure that a transparent surface exists, then return it.
   RefPtr<gfxASurface> EnsureTransparentSurface();
 
-  HDC GetTransparentDC() const {
+  HDC GetTransparentDC() const override {
     return mMemoryDC;
   }
   HWND GetHwnd() const {
     return mWnd;
   }
 
 private:
   HDC GetWindowSurface();
   void FreeWindowSurface(HDC dc);
 
-  void CreateTransparentSurface(int32_t aWidth, int32_t aHeight);
+  void CreateTransparentSurface(const gfx::IntSize& aSize);
 
 private:
   nsWindow* mWindow;
   uintptr_t mWidgetKey;
   HWND mWnd;
   gfx::CriticalSection mPresentLock;
 
   // Transparency handling.
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -1287,18 +1287,18 @@ NS_METHOD nsWindow::Show(bool bState)
       if (!wasVisible && (mWindowType == eWindowType_toplevel || mWindowType == eWindowType_dialog)) {
         // when a toplevel window or dialog is shown, initialize the UI state
         ::SendMessageW(mWnd, WM_CHANGEUISTATE, MAKEWPARAM(UIS_INITIALIZE, UISF_HIDEFOCUS | UISF_HIDEACCEL), 0);
       }
     } else {
       // Clear contents to avoid ghosting of old content if we display
       // this window again.
       if (wasVisible && mTransparencyMode == eTransparencyTransparent) {
-        if (RefPtr<WinCompositorWidget> proxy = GetCompositorWidget()) {
-          proxy->ClearTransparentWindow();
+        if (mCompositorWidgetDelegate) {
+          mCompositorWidgetDelegate->ClearTransparentWindow();
         }
       }
       if (mWindowType != eWindowType_dialog) {
         ::ShowWindow(mWnd, SW_HIDE);
       } else {
         ::SetWindowPos(mWnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE |
                        SWP_NOZORDER | SWP_NOACTIVATE);
       }
@@ -1546,18 +1546,18 @@ NS_METHOD nsWindow::Resize(double aWidth
   if (mBounds.width == width && mBounds.height == height) {
     if (aRepaint) {
       Invalidate();
     }
     return NS_OK;
   }
 
   if (mTransparencyMode == eTransparencyTransparent) {
-    if (RefPtr<WinCompositorWidget> proxy = GetCompositorWidget()) {
-      proxy->ResizeTransparentWindow(width, height);
+    if (mCompositorWidgetDelegate) {
+      mCompositorWidgetDelegate->ResizeTransparentWindow(gfx::IntSize(width, height));
     }
   }
 
   // Set cached value for lightweight and printing
   mBounds.width  = width;
   mBounds.height = height;
 
   if (mWnd) {
@@ -1605,18 +1605,18 @@ NS_METHOD nsWindow::Resize(double aX, do
       mBounds.width == width && mBounds.height == height) {
     if (aRepaint) {
       Invalidate();
     }
     return NS_OK;
   }
 
   if (eTransparencyTransparent == mTransparencyMode) {
-    if (RefPtr<WinCompositorWidget> proxy = GetCompositorWidget()) {
-      proxy->ResizeTransparentWindow(width, height);
+    if (mCompositorWidgetDelegate) {
+      mCompositorWidgetDelegate->ResizeTransparentWindow(gfx::IntSize(width, height));
     }
   }
 
   // Set cached value for lightweight and printing
   mBounds.x      = x;
   mBounds.y      = y;
   mBounds.width  = width;
   mBounds.height = height;
@@ -3618,25 +3618,26 @@ 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);
+    MOZ_ASSERT(!mCompositorWidgetDelegate);
 
     // Ensure we have a widget proxy even if we're not using the compositor,
     // since all our transparent window handling lives there.
     CompositorWidgetInitData initData(
       reinterpret_cast<uintptr_t>(mWnd),
       reinterpret_cast<uintptr_t>(static_cast<nsIWidget*>(this)),
       mTransparencyMode);
-    mCompositorWidget = new WinCompositorWidget(initData, this);
+    mBasicLayersSurface = new WinCompositorWidget(initData, this);
+    mCompositorWidgetDelegate = mBasicLayersSurface;
     mLayerManager = CreateBasicLayerManager();
   }
 
   NS_ASSERTION(mLayerManager, "Couldn't provide a valid layer manager.");
 
   return mLayerManager;
 }
 
@@ -3687,22 +3688,16 @@ nsWindow::OnDefaultButtonLoaded(const La
 
   if (!::SetCursorPos(centerOfButton.x, centerOfButton.y)) {
     NS_ERROR("SetCursorPos failed");
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
-mozilla::widget::WinCompositorWidget*
-nsWindow::GetCompositorWidget()
-{
-  return mCompositorWidget? mCompositorWidget->AsWindows() : nullptr;
-}
-
 void
 nsWindow::UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries)
 {
   RefPtr<LayerManager> layerManager = GetLayerManager();
   if (!layerManager) {
     return;
   }
 
@@ -4895,27 +4890,26 @@ nsWindow::ProcessMessage(UINT msg, WPARA
       {
         // From msdn, the way around this is to disable the visible state
         // temporarily. We need the text to be set but we don't want the
         // redraw to occur. However, we need to make sure that we don't
         // do this at the same time that a Present is happening.
         //
         // To do this we take mPresentLock in nsWindow::PreRender and
         // if that lock is taken we wait before doing WM_SETTEXT
-        RefPtr<WinCompositorWidget> proxy = GetCompositorWidget();
-        if (proxy) {
-          proxy->EnterPresentLock();
+        if (mCompositorWidgetDelegate) {
+          mCompositorWidgetDelegate->EnterPresentLock();
         }
         DWORD style = GetWindowLong(mWnd, GWL_STYLE);
         SetWindowLong(mWnd, GWL_STYLE, style & ~WS_VISIBLE);
         *aRetValue = CallWindowProcW(GetPrevWindowProc(), mWnd,
                                      msg, wParam, lParam);
         SetWindowLong(mWnd, GWL_STYLE, style);
-        if (proxy) {
-          proxy->LeavePresentLock();
+        if (mCompositorWidgetDelegate) {
+          mCompositorWidgetDelegate->LeavePresentLock();
         }
 
         return true;
       }
 
     case WM_NCACTIVATE:
     {
       /*
@@ -6206,18 +6200,18 @@ void nsWindow::OnWindowPosChanged(WINDOW
 
     ::GetWindowRect(mWnd, &r);
 
     newWidth  = r.right - r.left;
     newHeight = r.bottom - r.top;
     nsIntRect rect(wp->x, wp->y, newWidth, newHeight);
 
     if (eTransparencyTransparent == mTransparencyMode) {
-      if (RefPtr<WinCompositorWidget> proxy = GetCompositorWidget()) {
-        proxy->ResizeTransparentWindow(newWidth, newHeight);
+      if (mCompositorWidgetDelegate) {
+        mCompositorWidgetDelegate->ResizeTransparentWindow(gfx::IntSize(newWidth, newHeight));
       }
     }
 
     if (newWidth > mLastSize.width)
     {
       RECT drect;
 
       // getting wider
@@ -6727,19 +6721,20 @@ void nsWindow::OnDestroy()
     VERIFY(::DeleteObject(mBrush));
     mBrush = nullptr;
   }
 
   // Destroy any custom cursor resources.
   if (mCursor == -1)
     SetCursor(eCursor_standard);
 
-  if (RefPtr<WinCompositorWidget> proxy = GetCompositorWidget()) {
-    proxy->OnDestroyWindow();
-  }
+  if (mCompositorWidgetDelegate) {
+    mCompositorWidgetDelegate->OnDestroyWindow();
+  }
+  mBasicLayersSurface = nullptr;
 
   // Finalize panning feedback to possibly restore window displacement
   mGesture.PanFeedbackFinalize(mWnd, true);
 
   // Clear the main HWND.
   mWnd = nullptr;
 }
 
@@ -7044,18 +7039,18 @@ void nsWindow::SetWindowTranslucencyInne
   VERIFY_WINDOW_STYLE(style);
   ::SetWindowLongPtrW(hWnd, GWL_STYLE, style);
   ::SetWindowLongPtrW(hWnd, GWL_EXSTYLE, exStyle);
 
   if (HasGlass())
     memset(&mGlassMargins, 0, sizeof mGlassMargins);
   mTransparencyMode = aMode;
 
-  if (RefPtr<WinCompositorWidget> proxy = GetCompositorWidget()) {
-    proxy->UpdateTransparency(aMode);
+  if (mCompositorWidgetDelegate) {
+    mCompositorWidgetDelegate->UpdateTransparency(aMode);
   }
   UpdateGlass();
 }
 
 #endif //MOZ_XUL
 
 /**************************************************************
  **************************************************************
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -52,18 +52,18 @@
 
 class nsNativeDragTarget;
 class nsIRollupListener;
 class imgIContainer;
 
 namespace mozilla {
 namespace widget {
 class NativeKey;
+class WinCompositorWidget;
 struct MSGResult;
-class WinCompositorWidget;
 } // namespace widget
 } // namespacw mozilla;
 
 /**
  * Native WIN32 window wrapper.
  */
 
 class nsWindow : public nsWindowBase
@@ -483,18 +483,16 @@ protected:
   virtual nsresult        SetWindowClipRegion(const nsTArray<LayoutDeviceIntRect>& aRects,
                                               bool aIntersectWithExisting) override;
   nsIntRegion             GetRegionToPaint(bool aForceFullRepaint, 
                                            PAINTSTRUCT ps, HDC aDC);
   static void             ActivateOtherWindowHelper(HWND aWnd);
   void                    ClearCachedResources();
   nsIWidgetListener*      GetPaintListener();
 
-  mozilla::widget::WinCompositorWidget* GetCompositorWidget();
-
 protected:
   nsCOMPtr<nsIWidget>   mParent;
   nsIntSize             mLastSize;
   nsIntPoint            mLastPoint;
   HWND                  mWnd;
   HWND                  mTransitionWnd;
   WNDPROC               mPrevWndProc;
   HBRUSH                mBrush;
@@ -617,16 +615,18 @@ protected:
   //  painting too rapidly in response to frequent input events.
   TimeStamp mLastPaintEndTime;
 
   // Caching for hit test results
   POINT mCachedHitTestPoint;
   TimeStamp mCachedHitTestTime;
   int32_t mCachedHitTestResult;
 
+  RefPtr<mozilla::widget::WinCompositorWidget> mBasicLayersSurface;
+
   static bool sNeedsToInitMouseWheelSettings;
   static void InitMouseWheelScrollData();
 
   double mSizeConstraintsScale; // scale in effect when setting constraints
 };
 
 /**
  * A child window is a window with different style.
--- a/widget/windows/nsWindowGfx.cpp
+++ b/widget/windows/nsWindowGfx.cpp
@@ -234,17 +234,17 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t
     // we force generation of WM_PAINT messages by invalidating window areas with
     // RedrawWindow, InvalidateRect or InvalidateRgn function calls.
     // BeginPaint/EndPaint must be called to make Windows think that invalid area
     // is painted. Otherwise it will continue sending the same message endlessly.
     ::BeginPaint(mWnd, &ps);
     ::EndPaint(mWnd, &ps);
 
     // We're guaranteed to have a widget proxy since we called GetLayerManager().
-    aDC = GetCompositorWidget()->GetTransparentDC();
+    aDC = mCompositorWidgetDelegate->GetTransparentDC();
   }
 #endif
 
   mPainting = true;
 
 #ifdef WIDGET_DEBUG_OUTPUT
   HRGN debugPaintFlashRegion = nullptr;
   HDC debugPaintFlashDC = nullptr;
@@ -308,17 +308,17 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t
     switch (GetLayerManager()->GetBackendType()) {
       case LayersBackend::LAYERS_BASIC:
         {
           RefPtr<gfxASurface> targetSurface;
 
 #if defined(MOZ_XUL)
           // don't support transparency for non-GDI rendering, for now
           if (eTransparencyTransparent == mTransparencyMode) {
-            targetSurface = GetCompositorWidget()->EnsureTransparentSurface();
+            targetSurface = mBasicLayersSurface->EnsureTransparentSurface();
           }
 #endif
 
           RefPtr<gfxWindowsSurface> targetSurfaceWin;
           if (!targetSurface)
           {
             uint32_t flags = (mTransparencyMode == eTransparencyOpaque) ? 0 :
                 gfxWindowsSurface::FLAG_IS_TRANSPARENT;
@@ -373,17 +373,17 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t
               this, LayoutDeviceIntRegion::FromUnknownRegion(region));
           }
 
 #ifdef MOZ_XUL
           if (eTransparencyTransparent == mTransparencyMode) {
             // Data from offscreen drawing surface was copied to memory bitmap of transparent
             // bitmap. Now it can be read from memory bitmap to apply alpha channel and after
             // that displayed on the screen.
-            GetCompositorWidget()->RedrawTransparentWindow();
+            mBasicLayersSurface->RedrawTransparentWindow();
           }
 #endif
         }
         break;
       case LayersBackend::LAYERS_CLIENT:
         {
           result = listener->PaintWindow(
             this, LayoutDeviceIntRegion::FromUnknownRegion(region));