Bug 1425842 - Rename X11CompositorWidget to GtkCompositorWidget and implement WindowSurfaceWayland support, r?jhorak draft
authorMartin Stransky <stransky@redhat.com>
Mon, 18 Dec 2017 20:20:02 +0100
changeset 714006 10b5e8d71a6763b97c71484820d86ed9a723b9d1
parent 712645 5572465c08a9ce0671dcd01c721f9356fcd53a65
child 744486 20582305c7018e9c05c9743a4f77738fa461a2cf
push id93809
push userstransky@redhat.com
push dateThu, 21 Dec 2017 13:15:11 +0000
reviewersjhorak
bugs1425842
milestone59.0a1
Bug 1425842 - Rename X11CompositorWidget to GtkCompositorWidget and implement WindowSurfaceWayland support, r?jhorak - Rename X11CompositorWidget to GtkCompositorWidget to handle both X11 and Wayland backends. - Rename X11CompositorWidgetInitData to GtkCompositorWidgetInitData - Implement Wayland support at WindowSurfaceProvider, WindowSurfaceProvider::CreateWindowSurface() is able to create WindowSurfaceWayland. - Initialize Wayland surface provider at nsWindow::Create() MozReview-Commit-ID: 1WvR9nWHa3L
gfx/gl/GLContextProviderGLX.cpp
widget/CompositorWidget.h
widget/gtk/CompositorWidgetChild.h
widget/gtk/CompositorWidgetParent.cpp
widget/gtk/CompositorWidgetParent.h
widget/gtk/GtkCompositorWidget.cpp
widget/gtk/GtkCompositorWidget.h
widget/gtk/InProcessGtkCompositorWidget.cpp
widget/gtk/InProcessGtkCompositorWidget.h
widget/gtk/InProcessX11CompositorWidget.cpp
widget/gtk/InProcessX11CompositorWidget.h
widget/gtk/PlatformWidgetTypes.ipdlh
widget/gtk/WindowSurfaceProvider.cpp
widget/gtk/WindowSurfaceProvider.h
widget/gtk/X11CompositorWidget.cpp
widget/gtk/X11CompositorWidget.h
widget/gtk/moz.build
widget/gtk/nsWindow.cpp
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -12,17 +12,17 @@
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include "X11UndefineNone.h"
 
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/layers/CompositorOptions.h"
 #include "mozilla/widget/CompositorWidget.h"
-#include "mozilla/widget/X11CompositorWidget.h"
+#include "mozilla/widget/GtkCompositorWidget.h"
 #include "mozilla/Unused.h"
 
 #include "prenv.h"
 #include "GLContextProvider.h"
 #include "GLLibraryLoader.h"
 #include "nsDebug.h"
 #include "nsIWidget.h"
 #include "GLXLibrary.h"
@@ -798,17 +798,17 @@ CreateForWidget(Display* aXDisplay, Wind
     }
     return GLContextGLX::CreateGLContext(flags, SurfaceCaps::Any(), false, aXDisplay,
                                          aXWindow, config, false, nullptr);
 }
 
 already_AddRefed<GLContext>
 GLContextProviderGLX::CreateForCompositorWidget(CompositorWidget* aCompositorWidget, bool aForceAccelerated)
 {
-    X11CompositorWidget* compWidget = aCompositorWidget->AsX11();
+    GtkCompositorWidget* compWidget = aCompositorWidget->AsX11();
     MOZ_ASSERT(compWidget);
 
     return CreateForWidget(compWidget->XDisplay(),
                            compWidget->XWindow(),
                            compWidget->GetCompositorOptions().UseWebRender(),
                            aForceAccelerated);
 }
 
--- a/widget/CompositorWidget.h
+++ b/widget/CompositorWidget.h
@@ -28,17 +28,17 @@ class Compositor;
 } // namespace layers
 namespace gfx {
 class DrawTarget;
 class SourceSurface;
 } // namespace gfx
 namespace widget {
 
 class WinCompositorWidget;
-class X11CompositorWidget;
+class GtkCompositorWidget;
 class AndroidCompositorWidget;
 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.
@@ -282,17 +282,17 @@ public:
   /**
    * This is only used by out-of-process compositors.
    */
   virtual RefPtr<VsyncObserver> GetVsyncObserver() const;
 
   virtual WinCompositorWidget* AsWindows() {
     return nullptr;
   }
-  virtual X11CompositorWidget* AsX11() {
+  virtual GtkCompositorWidget* AsX11() {
     return nullptr;
   }
   virtual AndroidCompositorWidget* AsAndroid() {
     return nullptr;
   }
 
   /**
    * Return the platform-specific delegate for the widget, if any.
--- a/widget/gtk/CompositorWidgetChild.h
+++ b/widget/gtk/CompositorWidgetChild.h
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #ifndef widget_gtk_CompositorWidgetChild_h
 #define widget_gtk_CompositorWidgetChild_h
 
-#include "X11CompositorWidget.h"
+#include "GtkCompositorWidget.h"
 #include "mozilla/widget/PCompositorWidgetChild.h"
 #include "mozilla/widget/CompositorWidgetVsyncObserver.h"
 
 namespace mozilla {
 namespace widget {
 
 class CompositorWidgetChild final
  : public PCompositorWidgetChild
--- a/widget/gtk/CompositorWidgetParent.cpp
+++ b/widget/gtk/CompositorWidgetParent.cpp
@@ -7,17 +7,17 @@
 #include "mozilla/Unused.h"
 #include "mozilla/widget/PlatformWidgetTypes.h"
 
 namespace mozilla {
 namespace widget {
 
 CompositorWidgetParent::CompositorWidgetParent(const CompositorWidgetInitData& aInitData,
                                                const layers::CompositorOptions& aOptions)
- : X11CompositorWidget(aInitData.get_X11CompositorWidgetInitData(), aOptions)
+ : GtkCompositorWidget(aInitData.get_GtkCompositorWidgetInitData(), aOptions)
 {
   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_GPU);
 }
 
 CompositorWidgetParent::~CompositorWidgetParent()
 {
 }
 
--- a/widget/gtk/CompositorWidgetParent.h
+++ b/widget/gtk/CompositorWidgetParent.h
@@ -1,25 +1,25 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #ifndef widget_gtk_CompositorWidgetParent_h
 #define widget_gtk_CompositorWidgetParent_h
 
-#include "X11CompositorWidget.h"
+#include "GtkCompositorWidget.h"
 #include "mozilla/widget/PCompositorWidgetParent.h"
 
 namespace mozilla {
 namespace widget {
 
 class CompositorWidgetParent final
  : public PCompositorWidgetParent,
-   public X11CompositorWidget
+   public GtkCompositorWidget
 {
 public:
   explicit CompositorWidgetParent(const CompositorWidgetInitData& aInitData,
                                   const layers::CompositorOptions& aOptions);
   ~CompositorWidgetParent() override;
 
   void ActorDestroy(ActorDestroyReason aWhy) override { }
 
rename from widget/gtk/X11CompositorWidget.cpp
rename to widget/gtk/GtkCompositorWidget.cpp
--- a/widget/gtk/X11CompositorWidget.cpp
+++ b/widget/gtk/GtkCompositorWidget.cpp
@@ -1,110 +1,119 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 "X11CompositorWidget.h"
+#include "GtkCompositorWidget.h"
 
 #include "gfxPlatformGtk.h"
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/widget/InProcessCompositorWidget.h"
 #include "mozilla/widget/PlatformWidgetTypes.h"
 #include "nsWindow.h"
 
 namespace mozilla {
 namespace widget {
 
-X11CompositorWidget::X11CompositorWidget(const X11CompositorWidgetInitData& aInitData,
-                                         const CompositorOptions& aOptions,
+GtkCompositorWidget::GtkCompositorWidget(const GtkCompositorWidgetInitData& aInitData,
+                                         const layers::CompositorOptions& aOptions,
                                          nsWindow* aWindow)
       : CompositorWidget(aOptions)
       , mWidget(aWindow)
 {
   // If we have a nsWindow, then grab the already existing display connection
   // If we don't, then use the init data to connect to the display
   if (aWindow) {
     mXDisplay = aWindow->XDisplay();
   } else {
     mXDisplay = XOpenDisplay(aInitData.XDisplayString().get());
   }
-  mXWindow = (Window)aInitData.XWindow();
 
-  // Grab the window's visual and depth
-  XWindowAttributes windowAttrs;
-  XGetWindowAttributes(mXDisplay, mXWindow, &windowAttrs);
-
-  Visual*   visual = windowAttrs.visual;
-  int       depth = windowAttrs.depth;
+#ifdef MOZ_WAYLAND
+  if (!mXDisplay) {
+    MOZ_RELEASE_ASSERT(aWindow,
+      "We're running on Wayland and but without valid nsWindow.");
+    mProvider.Initialize(aWindow);
+  } else
+#endif
+  {
+    mXWindow = (Window)aInitData.XWindow();
 
-  // Initialize the window surface provider
-  mProvider.Initialize(
-    mXDisplay,
-    mXWindow,
-    visual,
-    depth
-    );
+    // Grab the window's visual and depth
+    XWindowAttributes windowAttrs;
+    XGetWindowAttributes(mXDisplay, mXWindow, &windowAttrs);
+
+    Visual*   visual = windowAttrs.visual;
+    int       depth = windowAttrs.depth;
 
+    // Initialize the window surface provider
+    mProvider.Initialize(
+      mXDisplay,
+      mXWindow,
+      visual,
+      depth
+      );
+  }
   mClientSize = aInitData.InitialClientSize();
 }
 
-X11CompositorWidget::~X11CompositorWidget()
+GtkCompositorWidget::~GtkCompositorWidget()
 {
   mProvider.CleanupResources();
 
   // If we created our own display connection, we need to destroy it
   if (!mWidget && mXDisplay) {
     XCloseDisplay(mXDisplay);
     mXDisplay = nullptr;
   }
 }
 
 already_AddRefed<gfx::DrawTarget>
-X11CompositorWidget::StartRemoteDrawing()
+GtkCompositorWidget::StartRemoteDrawing()
 {
   return nullptr;
 }
 void
-X11CompositorWidget::EndRemoteDrawing()
+GtkCompositorWidget::EndRemoteDrawing()
 {
 }
 
 already_AddRefed<gfx::DrawTarget>
-X11CompositorWidget::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion,
+GtkCompositorWidget::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion,
                                                 layers::BufferMode* aBufferMode)
 {
   return mProvider.StartRemoteDrawingInRegion(aInvalidRegion,
                                               aBufferMode);
 }
 
-void X11CompositorWidget::EndRemoteDrawingInRegion(gfx::DrawTarget* aDrawTarget,
+void GtkCompositorWidget::EndRemoteDrawingInRegion(gfx::DrawTarget* aDrawTarget,
                               LayoutDeviceIntRegion& aInvalidRegion)
 {
   mProvider.EndRemoteDrawingInRegion(aDrawTarget,
                                      aInvalidRegion);
 }
 
-nsIWidget* X11CompositorWidget::RealWidget()
+nsIWidget* GtkCompositorWidget::RealWidget()
 {
   return mWidget;
 }
 
 void
-X11CompositorWidget::NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize)
+GtkCompositorWidget::NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize)
 {
   mClientSize = aClientSize;
 }
 
 LayoutDeviceIntSize
-X11CompositorWidget::GetClientSize()
+GtkCompositorWidget::GetClientSize()
 {
   return mClientSize;
 }
 
 uintptr_t
-X11CompositorWidget::GetWidgetKey()
+GtkCompositorWidget::GetWidgetKey()
 {
   return reinterpret_cast<uintptr_t>(mWidget);
 }
 
 } // namespace widget
 } // namespace mozilla
rename from widget/gtk/X11CompositorWidget.h
rename to widget/gtk/GtkCompositorWidget.h
--- a/widget/gtk/X11CompositorWidget.h
+++ b/widget/gtk/GtkCompositorWidget.h
@@ -1,15 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
-#ifndef widget_gtk_X11CompositorWidget_h
-#define widget_gtk_X11CompositorWidget_h
+#ifndef widget_gtk_GtkCompositorWidget_h
+#define widget_gtk_GtkCompositorWidget_h
 
 #include "mozilla/widget/CompositorWidget.h"
 #include "WindowSurfaceProvider.h"
 
 class nsIWidget;
 class nsWindow;
 
 namespace mozilla {
@@ -23,44 +23,44 @@ public:
 
   // CompositorWidgetDelegate Overrides
 
   PlatformCompositorWidgetDelegate* AsPlatformSpecificDelegate() override {
     return this;
   }
 };
 
-class X11CompositorWidgetInitData;
+class GtkCompositorWidgetInitData;
 
-class X11CompositorWidget
+class GtkCompositorWidget
  : public CompositorWidget
  , public PlatformCompositorWidgetDelegate
 {
 public:
-  X11CompositorWidget(const X11CompositorWidgetInitData& aInitData,
+  GtkCompositorWidget(const GtkCompositorWidgetInitData& aInitData,
                       const layers::CompositorOptions& aOptions,
                       nsWindow* aWindow = nullptr);
-  ~X11CompositorWidget();
+  ~GtkCompositorWidget();
 
   // CompositorWidget Overrides
 
   already_AddRefed<gfx::DrawTarget> StartRemoteDrawing() override;
   void EndRemoteDrawing() override;
 
   already_AddRefed<gfx::DrawTarget>
   StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion,
                              layers::BufferMode* aBufferMode) override;
   void EndRemoteDrawingInRegion(gfx::DrawTarget* aDrawTarget,
                                 LayoutDeviceIntRegion& aInvalidRegion) override;
   uintptr_t GetWidgetKey() override;
 
   LayoutDeviceIntSize GetClientSize() override;
 
   nsIWidget* RealWidget() override;
-  X11CompositorWidget* AsX11() override { return this; }
+  GtkCompositorWidget* AsX11() override { return this; }
   CompositorWidgetDelegate* AsDelegate() override { return this; }
 
   Display* XDisplay() const { return mXDisplay; }
   Window XWindow() const { return mXWindow; }
 
   // PlatformCompositorWidgetDelegate Overrides
 
   void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) override;
@@ -74,9 +74,9 @@ private:
   Display* mXDisplay;
   Window   mXWindow;
   WindowSurfaceProvider mProvider;
 };
 
 } // namespace widget
 } // namespace mozilla
 
-#endif // widget_gtk_X11CompositorWidget_h
+#endif // widget_gtk_GtkCompositorWidget_h
rename from widget/gtk/InProcessX11CompositorWidget.cpp
rename to widget/gtk/InProcessGtkCompositorWidget.cpp
--- a/widget/gtk/InProcessX11CompositorWidget.cpp
+++ b/widget/gtk/InProcessGtkCompositorWidget.cpp
@@ -2,45 +2,45 @@
 /* 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 "HeadlessCompositorWidget.h"
 #include "HeadlessWidget.h"
 #include "mozilla/widget/PlatformWidgetTypes.h"
 
-#include "InProcessX11CompositorWidget.h"
+#include "InProcessGtkCompositorWidget.h"
 #include "nsWindow.h"
 
 namespace mozilla {
 namespace widget {
 
 /* static */ RefPtr<CompositorWidget>
 CompositorWidget::CreateLocal(const CompositorWidgetInitData& aInitData,
                               const layers::CompositorOptions& aOptions,
                               nsIWidget* aWidget)
 {
   if (aInitData.type() == CompositorWidgetInitData::THeadlessCompositorWidgetInitData) {
     return new HeadlessCompositorWidget(aInitData.get_HeadlessCompositorWidgetInitData(),
                                         aOptions, static_cast<HeadlessWidget*>(aWidget));
   } else {
-    return new InProcessX11CompositorWidget(aInitData.get_X11CompositorWidgetInitData(),
+    return new InProcessGtkCompositorWidget(aInitData.get_GtkCompositorWidgetInitData(),
                                             aOptions, static_cast<nsWindow*>(aWidget));
   }
 }
 
-InProcessX11CompositorWidget::InProcessX11CompositorWidget(const X11CompositorWidgetInitData& aInitData,
+InProcessGtkCompositorWidget::InProcessGtkCompositorWidget(const GtkCompositorWidgetInitData& aInitData,
                                                            const layers::CompositorOptions& aOptions,
                                                            nsWindow* aWindow)
-  : X11CompositorWidget(aInitData, aOptions, aWindow)
+  : GtkCompositorWidget(aInitData, aOptions, aWindow)
 {
 }
 
 void
-InProcessX11CompositorWidget::ObserveVsync(VsyncObserver* aObserver)
+InProcessGtkCompositorWidget::ObserveVsync(VsyncObserver* aObserver)
 {
   if (RefPtr<CompositorVsyncDispatcher> cvd = mWidget->GetCompositorVsyncDispatcher()) {
     cvd->SetCompositorVsyncObserver(aObserver);
   }
 }
 
 } // namespace widget
 } // namespace mozilla
rename from widget/gtk/InProcessX11CompositorWidget.h
rename to widget/gtk/InProcessGtkCompositorWidget.h
--- a/widget/gtk/InProcessX11CompositorWidget.h
+++ b/widget/gtk/InProcessGtkCompositorWidget.h
@@ -1,31 +1,31 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
-#ifndef widget_gtk_InProcessX11CompositorWidgetParent_h
-#define widget_gtk_InProcessX11CompositorWidgetParent_h
+#ifndef widget_gtk_InProcessGtkCompositorWidgetParent_h
+#define widget_gtk_InProcessGtkCompositorWidgetParent_h
 
-#include "X11CompositorWidget.h"
+#include "GtkCompositorWidget.h"
 
 class nsWindow;
 
 namespace mozilla {
 namespace widget {
 
-class InProcessX11CompositorWidget final : public X11CompositorWidget
+class InProcessGtkCompositorWidget final : public GtkCompositorWidget
 {
 public:
-  InProcessX11CompositorWidget(const X11CompositorWidgetInitData& aInitData,
+  InProcessGtkCompositorWidget(const GtkCompositorWidgetInitData& aInitData,
                                const layers::CompositorOptions& aOptions,
                                nsWindow* aWindow);
 
   // CompositorWidgetDelegate
 
   void ObserveVsync(VsyncObserver* aObserver) override;
 };
 
 } // namespace widget
 } // namespace mozilla
 
-#endif // widget_gtk_InProcessX11CompositorWidgetParent_h
+#endif // widget_gtk_InProcessGtkCompositorWidgetParent_h
--- a/widget/gtk/PlatformWidgetTypes.ipdlh
+++ b/widget/gtk/PlatformWidgetTypes.ipdlh
@@ -6,24 +6,24 @@
 
 include HeadlessWidgetTypes;
 
 using mozilla::LayoutDeviceIntSize from "Units.h";
 
 namespace mozilla {
 namespace widget {
 
-struct X11CompositorWidgetInitData
+struct GtkCompositorWidgetInitData
 {
   uintptr_t           XWindow;
   nsCString           XDisplayString;
 
   LayoutDeviceIntSize InitialClientSize;
 };
 
 union CompositorWidgetInitData
 {
-  X11CompositorWidgetInitData;
+  GtkCompositorWidgetInitData;
   HeadlessCompositorWidgetInitData;
 };
 
 } // namespace widget
 } // namespace mozilla
--- a/widget/gtk/WindowSurfaceProvider.cpp
+++ b/widget/gtk/WindowSurfaceProvider.cpp
@@ -6,29 +6,36 @@
 
 #include "WindowSurfaceProvider.h"
 
 #include "gfxPlatformGtk.h"
 #include "mozilla/layers/LayersTypes.h"
 #include "WindowSurfaceX11Image.h"
 #include "WindowSurfaceX11SHM.h"
 #include "WindowSurfaceXRender.h"
+#ifdef MOZ_WAYLAND
+#include "WindowSurfaceWayland.h"
+#endif
 
 namespace mozilla {
 namespace widget {
 
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 
 WindowSurfaceProvider::WindowSurfaceProvider()
-    : mXDisplay(nullptr)
+    : mIsX11Display(false)
+    , mXDisplay(nullptr)
     , mXWindow(0)
     , mXVisual(nullptr)
     , mXDepth(0)
     , mWindowSurface(nullptr)
+#ifdef MOZ_WAYLAND
+    , mWidget(nullptr)
+#endif
 {
 }
 
 void WindowSurfaceProvider::Initialize(
       Display* aDisplay,
       Window aWindow,
       Visual* aVisual,
       int aDepth)
@@ -38,25 +45,45 @@ void WindowSurfaceProvider::Initialize(
 
   // This should also be a valid initialization
   MOZ_ASSERT(aDisplay && aWindow != X11None && aVisual);
 
   mXDisplay = aDisplay;
   mXWindow = aWindow;
   mXVisual = aVisual;
   mXDepth = aDepth;
+  mIsX11Display = true;
 }
+
+#ifdef MOZ_WAYLAND
+void WindowSurfaceProvider::Initialize(nsWindow *aWidget)
+{
+  MOZ_ASSERT(!aWidget->IsX11Display(),
+             "We are supposed to have a Wayland display!");
+
+  mWidget = aWidget;
+  mIsX11Display = false;
+}
+#endif
+
 void WindowSurfaceProvider::CleanupResources()
 {
   mWindowSurface = nullptr;
 }
 
 UniquePtr<WindowSurface>
 WindowSurfaceProvider::CreateWindowSurface()
 {
+#ifdef MOZ_WAYLAND
+  if (!mIsX11Display) {
+    LOGDRAW(("Drawing to nsWindow %p using wl_surface\n", (void*)this));
+    return MakeUnique<WindowSurfaceWayland>(mWidget);
+  }
+#endif
+
   // We should be initialized
   MOZ_ASSERT(mXDisplay);
 
   // Blit to the window with the following priority:
   // 1. XRender (iff XRender is enabled && we are in-process)
   // 2. MIT-SHM
   // 3. XPutImage
 
@@ -89,17 +116,19 @@ WindowSurfaceProvider::StartRemoteDrawin
     mWindowSurface = CreateWindowSurface();
     if (!mWindowSurface)
       return nullptr;
   }
 
   *aBufferMode = BufferMode::BUFFER_NONE;
   RefPtr<DrawTarget> dt = nullptr;
   if (!(dt = mWindowSurface->Lock(aInvalidRegion)) &&
-      !mWindowSurface->IsFallback()) {
+      mIsX11Display && !mWindowSurface->IsFallback()) {
+    // We can't use WindowSurfaceX11Image fallback on Wayland but
+    // Lock() call on WindowSurfaceWayland should never fail.
     gfxWarningOnce() << "Failed to lock WindowSurface, falling back to XPutImage backend.";
     mWindowSurface = MakeUnique<WindowSurfaceX11Image>(mXDisplay, mXWindow, mXVisual, mXDepth);
     dt = mWindowSurface->Lock(aInvalidRegion);
   }
   return dt.forget();
 }
 
 void
--- a/widget/gtk/WindowSurfaceProvider.h
+++ b/widget/gtk/WindowSurfaceProvider.h
@@ -7,25 +7,31 @@
 #ifndef _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_PROVIDER_H
 #define _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_PROVIDER_H
 
 #include "mozilla/widget/WindowSurface.h"
 #include "mozilla/gfx/Types.h"
 #include "mozilla/gfx/2D.h"
 #include "Units.h"
 
+#include <gdk/gdk.h>
+#ifdef MOZ_WAYLAND
+#include <gdk/gdkwayland.h>
+#endif
 #include <X11/Xlib.h> // for Window, Display, Visual, etc.
 
+class nsWindow;
+
 namespace mozilla {
 namespace widget {
 
 /*
  * Holds the logic for creating WindowSurface's for a GTK nsWindow.
  * The main purpose of this class is to allow sharing of logic between
- * nsWindow and X11CompositorWidget, for when OMTC is enabled or disabled.
+ * nsWindow and GtkCompositorWidget, for when OMTC is enabled or disabled.
  */
 class WindowSurfaceProvider final
 {
 public:
   WindowSurfaceProvider();
 
   /**
    * Initializes the WindowSurfaceProvider by giving it the window
@@ -34,36 +40,44 @@ public:
    * while WindowSurfaceProvider is used.
    */
   void Initialize(
       Display* aDisplay,
       Window aWindow,
       Visual* aVisual,
       int aDepth);
 
+#ifdef MOZ_WAYLAND
+   void Initialize(nsWindow *aWidget);
+#endif
+
   /**
    * Releases any surfaces created by this provider.
-   * This is used by X11CompositorWidget to get rid
+   * This is used by GtkCompositorWidget to get rid
    * of resources before we close the display connection.
    */
   void CleanupResources();
 
   already_AddRefed<gfx::DrawTarget>
   StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion,
                              layers::BufferMode* aBufferMode);
   void EndRemoteDrawingInRegion(gfx::DrawTarget* aDrawTarget,
                                 LayoutDeviceIntRegion& aInvalidRegion);
 
 private:
   UniquePtr<WindowSurface> CreateWindowSurface();
 
-  Display*  mXDisplay;
-  Window    mXWindow;
-  Visual*   mXVisual;
-  int       mXDepth;
-
+  // Can we access X?
+  bool        mIsX11Display;
+  Display*    mXDisplay;
+  Window      mXWindow;
+  Visual*     mXVisual;
+  int         mXDepth;
   UniquePtr<WindowSurface> mWindowSurface;
+#ifdef MOZ_WAYLAND
+  nsWindow*   mWidget;
+#endif
 };
 
 }  // namespace widget
 }  // namespace mozilla
 
 #endif // _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_PROVIDER_H
--- a/widget/gtk/moz.build
+++ b/widget/gtk/moz.build
@@ -50,25 +50,25 @@ UNIFIED_SOURCES += [
 SOURCES += [
     'nsWindow.cpp', # conflicts with X11 headers
 ]
 
 if CONFIG['MOZ_X11']:
     UNIFIED_SOURCES += [
         'CompositorWidgetChild.cpp',
         'CompositorWidgetParent.cpp',
-        'InProcessX11CompositorWidget.cpp',
+        'GtkCompositorWidget.cpp',
+        'InProcessGtkCompositorWidget.cpp',
         'nsIdleServiceGTK.cpp',
-        'X11CompositorWidget.cpp',
     ]
     EXPORTS.mozilla.widget += [
         'CompositorWidgetChild.h',
         'CompositorWidgetParent.h',
-        'InProcessX11CompositorWidget.h',
-        'X11CompositorWidget.h',
+        'GtkCompositorWidget.h',
+        'InProcessGtkCompositorWidget.h',
     ]
 
 if CONFIG['NS_PRINTING']:
     UNIFIED_SOURCES += [
         'nsCUPSShim.cpp',
         'nsDeviceContextSpecG.cpp',
         'nsPrintDialogGTK.cpp',
         'nsPrintOptionsGTK.cpp',
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -117,17 +117,17 @@ using namespace mozilla::widget;
 #include "GLContextProvider.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/HelpersCairo.h"
 #include "mozilla/gfx/GPUProcessManager.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/layers/CompositorThread.h"
 
 #ifdef MOZ_X11
-#include "X11CompositorWidget.h"
+#include "GtkCompositorWidget.h"
 #include "gfxXlibSurface.h"
 #include "WindowSurfaceX11Image.h"
 #include "WindowSurfaceX11SHM.h"
 #include "WindowSurfaceXRender.h"
 #endif // MOZ_X11
 
 #include "nsShmImage.h"
 
@@ -2460,17 +2460,17 @@ nsWindow::OnSizeAllocate(GtkAllocation *
             LayoutDeviceIntRect(0, mBounds.height,
                                 size.width, size.height - mBounds.height));
         gdk_window_invalidate_rect(mGdkWindow, &rect, FALSE);
     }
 
     mBounds.SizeTo(size);
 
 #ifdef MOZ_X11
-    // Notify the X11CompositorWidget of a ClientSizeChange
+    // Notify the GtkCompositorWidget of a ClientSizeChange
     if (mCompositorWidgetDelegate) {
       mCompositorWidgetDelegate->NotifyClientSizeChanged(GetClientSize());
     }
 #endif
 
     // Gecko permits running nested event loops during processing of events,
     // GtkWindow callers of gtk_widget_size_allocate expect the signal
     // handlers to return sometime in the near future.
@@ -4057,18 +4057,22 @@ nsWindow::Create(nsIWidget* aParent,
       mXWindow = gdk_x11_window_get_xid(mGdkWindow);
 
       GdkVisual* gdkVisual = gdk_window_get_visual(mGdkWindow);
       mXVisual = gdk_x11_visual_get_xvisual(gdkVisual);
       mXDepth = gdk_visual_get_depth(gdkVisual);
 
       mSurfaceProvider.Initialize(mXDisplay, mXWindow, mXVisual, mXDepth);
     }
+#ifdef MOZ_WAYLAND
+    else if (!mIsX11Display) {
+      mSurfaceProvider.Initialize(this);
+    }
 #endif
-
+#endif
     return NS_OK;
 }
 
 void
 nsWindow::SetWindowClass(const nsAString &xulWinType)
 {
   if (!mShell)
     return;
@@ -4158,17 +4162,17 @@ nsWindow::NativeResize()
         allocation.height = size.height;
         gtk_widget_size_allocate(widget, &allocation);
     }
     else if (mGdkWindow) {
         gdk_window_resize(mGdkWindow, size.width, size.height);
     }
 
 #ifdef MOZ_X11
-    // Notify the X11CompositorWidget of a ClientSizeChange
+    // Notify the GtkCompositorWidget of a ClientSizeChange
     // This is different than OnSizeAllocate to catch initial sizing
     if (mCompositorWidgetDelegate) {
       mCompositorWidgetDelegate->NotifyClientSizeChanged(GetClientSize());
     }
 #endif
 
     // Does it need to be shown because bounds were previously insane?
     if (mNeedsShow && mIsShown) {
@@ -4214,17 +4218,17 @@ nsWindow::NativeMoveResize()
         gtk_widget_size_allocate(GTK_WIDGET(mContainer), &allocation);
     }
     else if (mGdkWindow) {
         gdk_window_move_resize(mGdkWindow,
                                topLeft.x, topLeft.y, size.width, size.height);
     }
 
 #ifdef MOZ_X11
-    // Notify the X11CompositorWidget of a ClientSizeChange
+    // Notify the GtkCompositorWidget of a ClientSizeChange
     // This is different than OnSizeAllocate to catch initial sizing
     if (mCompositorWidgetDelegate) {
       mCompositorWidgetDelegate->NotifyClientSizeChanged(GetClientSize());
     }
 #endif
 
     // Does it need to be shown because bounds were previously insane?
     if (mNeedsShow && mIsShown) {
@@ -7039,22 +7043,32 @@ nsWindow::GetCSDSupportLevel() {
 int32_t
 nsWindow::RoundsWidgetCoordinatesTo()
 {
     return GdkScaleFactor();
 }
 
 void nsWindow::GetCompositorWidgetInitData(mozilla::widget::CompositorWidgetInitData* aInitData)
 {
-  #ifdef MOZ_X11
-  *aInitData = mozilla::widget::X11CompositorWidgetInitData(
+#ifdef MOZ_X11
+#ifdef MOZ_WAYLAND
+  if (!mIsX11Display) {
+    *aInitData = mozilla::widget::GtkCompositorWidgetInitData(
+                                  (uintptr_t)nullptr,
+                                  nsCString(nullptr),
+                                  GetClientSize());
+  } else
+#endif
+  {
+    *aInitData = mozilla::widget::GtkCompositorWidgetInitData(
                                   mXWindow,
                                   nsCString(XDisplayString(mXDisplay)),
                                   GetClientSize());
-  #endif
+  }
+#endif
 }
 
 bool
 nsWindow::IsComposited() const
 {
   if (!mGdkWindow) {
     NS_WARNING("nsWindow::HasARGBVisual called before realization!");
     return false;