Bug 1514156 - Add RenderCompositorEGL for wayland r=nical
authorsotaro <sotaro.ikeda.g@gmail.com>
Tue, 12 Feb 2019 16:33:31 +0900
changeset 458692 19ccde31eaaa
parent 458691 d97a89ada9e6
child 458693 8b2e8f177263
push id35544
push userccoroiu@mozilla.com
push dateTue, 12 Feb 2019 16:29:08 +0000
treeherdermozilla-central@c849fb69e2e7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1514156
milestone67.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
Bug 1514156 - Add RenderCompositorEGL for wayland r=nical When GDK_BACKEND is wayland, widget is not fully mapped during creating CompositorSession. Needs to create valid EGLSurface after widget is fully mapped. Differential Revision: https://phabricator.services.mozilla.com/D18940
gfx/webrender_bindings/RenderCompositor.cpp
gfx/webrender_bindings/RenderCompositorEGL.cpp
gfx/webrender_bindings/RenderCompositorEGL.h
gfx/webrender_bindings/moz.build
widget/gtk/CompositorWidgetChild.cpp
widget/gtk/CompositorWidgetChild.h
widget/gtk/CompositorWidgetParent.cpp
widget/gtk/CompositorWidgetParent.h
widget/gtk/GtkCompositorWidget.cpp
widget/gtk/GtkCompositorWidget.h
widget/gtk/PCompositorWidget.ipdl
widget/gtk/mozcontainer.cpp
widget/gtk/mozcontainer.h
widget/gtk/nsWindow.cpp
widget/gtk/nsWindow.h
--- a/gfx/webrender_bindings/RenderCompositor.cpp
+++ b/gfx/webrender_bindings/RenderCompositor.cpp
@@ -11,26 +11,38 @@
 #include "mozilla/layers/SyncObject.h"
 #include "mozilla/webrender/RenderCompositorOGL.h"
 #include "mozilla/widget/CompositorWidget.h"
 
 #ifdef XP_WIN
 #  include "mozilla/webrender/RenderCompositorANGLE.h"
 #endif
 
+#ifdef MOZ_WAYLAND
+#include "mozilla/webrender/RenderCompositorEGL.h"
+#endif
+
 namespace mozilla {
 namespace wr {
 
 /* static */ UniquePtr<RenderCompositor> RenderCompositor::Create(
     RefPtr<widget::CompositorWidget>&& aWidget) {
 #ifdef XP_WIN
   if (gfx::gfxVars::UseWebRenderANGLE()) {
     return RenderCompositorANGLE::Create(std::move(aWidget));
   }
 #endif
+
+#ifdef MOZ_WAYLAND
+  UniquePtr<RenderCompositor> eglCompositor = RenderCompositorEGL::Create(aWidget);
+  if (eglCompositor) {
+    return eglCompositor;
+  }
+#endif
+
   return RenderCompositorOGL::Create(std::move(aWidget));
 }
 
 RenderCompositor::RenderCompositor(RefPtr<widget::CompositorWidget>&& aWidget)
     : mWidget(aWidget) {}
 
 RenderCompositor::~RenderCompositor() {}
 
new file mode 100644
--- /dev/null
+++ b/gfx/webrender_bindings/RenderCompositorEGL.cpp
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 "RenderCompositorEGL.h"
+
+#include "GLContext.h"
+#include "GLContextEGL.h"
+#include "GLContextProvider.h"
+#include "GLLibraryEGL.h"
+#include "mozilla/widget/CompositorWidget.h"
+#include "mozilla/widget/GtkCompositorWidget.h"
+
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+
+namespace mozilla {
+namespace wr {
+
+/* static */ UniquePtr<RenderCompositor> RenderCompositorEGL::Create(
+    RefPtr<widget::CompositorWidget> aWidget) {
+
+  if (GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
+    return nullptr;
+  }
+
+  RefPtr<gl::GLContext> gl;
+  gl = CreateGLContext(aWidget);
+  if (!gl) {
+    return nullptr;
+  }
+  return MakeUnique<RenderCompositorEGL>(gl, aWidget);
+}
+
+/* static */ already_AddRefed<gl::GLContext>
+RenderCompositorEGL::CreateGLContext(RefPtr<widget::CompositorWidget> aWidget) {
+  nsCString discardFailureId;
+
+  // Create GLContext with dummy EGLSurface.
+  RefPtr<gl::GLContext> gl =
+      //XXX headless context did not work.
+      gl::GLContextProviderEGL::CreateForCompositorWidget(aWidget, true);
+  if (!gl) {
+    gfxCriticalNote << "Failed GL context creation for WebRender: "
+                    << gfx::hexa(gl.get());
+    return nullptr;
+  }
+
+  if (!gl->MakeCurrent()) {
+    gfxCriticalNote << "Failed GL context creation for WebRender: "
+                    << gfx::hexa(gl.get());
+    return nullptr;
+  }
+
+  return gl.forget();
+}
+
+/* static */ EGLSurface RenderCompositorEGL::CreateEGLSurface(
+    widget::CompositorWidget* aWidget) {
+  EGLSurface surface = EGL_NO_SURFACE;
+  surface = gl::GLContextEGL::CreateEGLSurfaceForCompositorWidget(
+      aWidget, /* aForceAccelerated */ true);
+  if (surface == EGL_NO_SURFACE) {
+    gfxCriticalNote << "Failed to create EGLSurface";
+  }
+  return surface;
+}
+
+RenderCompositorEGL::RenderCompositorEGL(
+    RefPtr<gl::GLContext> aGL, RefPtr<widget::CompositorWidget> aWidget)
+    : RenderCompositor(std::move(aWidget)), mGL(aGL), mEGLSurface(EGL_NO_SURFACE) {
+  MOZ_ASSERT(mGL);
+}
+
+RenderCompositorEGL::~RenderCompositorEGL() {
+  DestroyEGLSurface();
+}
+
+bool RenderCompositorEGL::BeginFrame() {
+
+  if (mWidget->AsX11() && mWidget->AsX11()->WaylandRequestsUpdatingEGLSurface()) {
+    mEGLSurface = CreateEGLSurface(mWidget);
+    gl::GLContextEGL::Cast(gl())->SetEGLSurfaceOverride(mEGLSurface);
+  }
+
+  if (!mGL->MakeCurrent()) {
+    gfxCriticalNote << "Failed to make render context current, can't draw.";
+    return false;
+  }
+
+  return true;
+}
+
+void RenderCompositorEGL::EndFrame()
+{
+  if (mEGLSurface != EGL_NO_SURFACE) {
+    mGL->SwapBuffers();
+  }
+}
+
+void RenderCompositorEGL::WaitForGPU() {}
+
+void RenderCompositorEGL::Pause() {}
+
+bool RenderCompositorEGL::Resume() {
+  return true;
+}
+
+bool RenderCompositorEGL::MakeCurrent() {
+  gl::GLContextEGL::Cast(gl())->SetEGLSurfaceOverride(mEGLSurface);
+  return gl()->MakeCurrent();
+}
+
+void RenderCompositorEGL::DestroyEGLSurface() {
+  auto* egl = gl::GLLibraryEGL::Get();
+
+  // Release EGLSurface of back buffer before calling ResizeBuffers().
+  if (mEGLSurface) {
+    gl::GLContextEGL::Cast(gl())->SetEGLSurfaceOverride(EGL_NO_SURFACE);
+    egl->fDestroySurface(egl->Display(), mEGLSurface);
+    mEGLSurface = nullptr;
+  }
+}
+
+LayoutDeviceIntSize RenderCompositorEGL::GetBufferSize() {
+  return mWidget->GetClientSize();
+}
+
+}  // namespace wr
+}  // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/webrender_bindings/RenderCompositorEGL.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 MOZILLA_GFX_RENDERCOMPOSITOR_EGL_H
+#define MOZILLA_GFX_RENDERCOMPOSITOR_EGL_H
+
+#include "GLTypes.h"
+#include "mozilla/webrender/RenderCompositor.h"
+
+namespace mozilla {
+
+namespace wr {
+
+class RenderCompositorEGL : public RenderCompositor {
+ public:
+  static UniquePtr<RenderCompositor> Create(
+      RefPtr<widget::CompositorWidget> aWidget);
+
+  RenderCompositorEGL(RefPtr<gl::GLContext> aGL,
+                      RefPtr<widget::CompositorWidget> aWidget);
+  virtual ~RenderCompositorEGL();
+
+  bool BeginFrame() override;
+  void EndFrame() override;
+  void WaitForGPU() override;
+  void Pause() override;
+  bool Resume() override;
+
+  gl::GLContext* gl() const override { return mGL; }
+
+  bool MakeCurrent() override;
+
+  bool UseANGLE() const override { return false; }
+
+  LayoutDeviceIntSize GetBufferSize() override;
+
+ protected:
+   static already_AddRefed<gl::GLContext> CreateGLContext(
+      RefPtr<widget::CompositorWidget> aWidget);
+   static EGLSurface CreateEGLSurface(widget::CompositorWidget* aWidget);
+
+  void DestroyEGLSurface();
+
+  const RefPtr<gl::GLContext> mGL;
+  EGLSurface mEGLSurface;
+};
+
+}  // namespace wr
+}  // namespace mozilla
+
+#endif  // MOZILLA_GFX_RENDERCOMPOSITOR_EGL_H
--- a/gfx/webrender_bindings/moz.build
+++ b/gfx/webrender_bindings/moz.build
@@ -61,16 +61,24 @@ if CONFIG['MOZ_ENABLE_D3D10_LAYER']:
     ]
     UNIFIED_SOURCES += [
         'RenderD3D11TextureHostOGL.cpp',
     ]
     SOURCES += [
         'RenderCompositorANGLE.cpp',
     ]
 
+if CONFIG['MOZ_WAYLAND']:
+    EXPORTS.mozilla.webrender += [
+        'RenderCompositorEGL.h',
+    ]
+    SOURCES += [
+        'RenderCompositorEGL.cpp',
+    ]
+
 if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk3'):
     CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
     CXXFLAGS += CONFIG['CAIRO_FT_CFLAGS']
 
 if CONFIG['COMPILE_ENVIRONMENT']:
     GENERATED_FILES += [
         'webrender_ffi_generated.h',
     ]
@@ -87,10 +95,12 @@ if CONFIG['COMPILE_ENVIRONMENT']:
         '/gfx/wr/webrender_api',
     ]
 
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
+CXXFLAGS += CONFIG['TK_CFLAGS']
+
 if CONFIG['CC_TYPE'] == 'clang-cl':
     AllowCompilerWarnings()  # workaround for bug 1090497
--- a/widget/gtk/CompositorWidgetChild.cpp
+++ b/widget/gtk/CompositorWidgetChild.cpp
@@ -30,10 +30,16 @@ mozilla::ipc::IPCResult CompositorWidget
   return IPC_OK();
 }
 
 void CompositorWidgetChild::NotifyClientSizeChanged(
     const LayoutDeviceIntSize& aClientSize) {
   Unused << SendNotifyClientSizeChanged(aClientSize);
 }
 
+#ifdef MOZ_WAYLAND
+void CompositorWidgetChild::RequestsUpdatingEGLSurface() {
+  Unused << SendRequestsUpdatingEGLSurface();
+}
+#endif
+
 }  // namespace widget
 }  // namespace mozilla
--- a/widget/gtk/CompositorWidgetChild.h
+++ b/widget/gtk/CompositorWidgetChild.h
@@ -19,17 +19,19 @@ class CompositorWidgetChild final : publ
   CompositorWidgetChild(RefPtr<CompositorVsyncDispatcher> aVsyncDispatcher,
                         RefPtr<CompositorWidgetVsyncObserver> aVsyncObserver);
   ~CompositorWidgetChild() override;
 
   mozilla::ipc::IPCResult RecvObserveVsync() override;
   mozilla::ipc::IPCResult RecvUnobserveVsync() override;
 
   void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) override;
-
+#ifdef MOZ_WAYLAND
+  void RequestsUpdatingEGLSurface() override;
+#endif
  private:
   RefPtr<CompositorVsyncDispatcher> mVsyncDispatcher;
   RefPtr<CompositorWidgetVsyncObserver> mVsyncObserver;
 };
 
 }  // namespace widget
 }  // namespace mozilla
 
--- a/widget/gtk/CompositorWidgetParent.cpp
+++ b/widget/gtk/CompositorWidgetParent.cpp
@@ -35,10 +35,18 @@ RefPtr<VsyncObserver> CompositorWidgetPa
 }
 
 mozilla::ipc::IPCResult CompositorWidgetParent::RecvNotifyClientSizeChanged(
     const LayoutDeviceIntSize& aClientSize) {
   NotifyClientSizeChanged(aClientSize);
   return IPC_OK();
 }
 
+mozilla::ipc::IPCResult CompositorWidgetParent::RecvRequestsUpdatingEGLSurface()
+{
+#ifdef MOZ_WAYLAND
+  RequestsUpdatingEGLSurface();
+#endif
+  return IPC_OK();
+}
+
 }  // namespace widget
 }  // namespace mozilla
--- a/widget/gtk/CompositorWidgetParent.h
+++ b/widget/gtk/CompositorWidgetParent.h
@@ -22,16 +22,18 @@ class CompositorWidgetParent final : pub
   void ActorDestroy(ActorDestroyReason aWhy) override {}
 
   void ObserveVsync(VsyncObserver* aObserver) override;
   RefPtr<VsyncObserver> GetVsyncObserver() const override;
 
   mozilla::ipc::IPCResult RecvNotifyClientSizeChanged(
       const LayoutDeviceIntSize& aClientSize) override;
 
+  mozilla::ipc::IPCResult RecvRequestsUpdatingEGLSurface() override;
+
  private:
   RefPtr<VsyncObserver> mVsyncObserver;
 };
 
 }  // namespace widget
 }  // namespace mozilla
 
 #endif  // widget_gtk_CompositorWidgetParent_h
--- a/widget/gtk/GtkCompositorWidget.cpp
+++ b/widget/gtk/GtkCompositorWidget.cpp
@@ -80,16 +80,28 @@ void GtkCompositorWidget::EndRemoteDrawi
 
 nsIWidget* GtkCompositorWidget::RealWidget() { return mWidget; }
 
 void GtkCompositorWidget::NotifyClientSizeChanged(
     const LayoutDeviceIntSize& aClientSize) {
   mClientSize = aClientSize;
 }
 
+#ifdef MOZ_WAYLAND
+void GtkCompositorWidget::RequestsUpdatingEGLSurface() {
+  mWaylandRequestsUpdatingEGLSurface = true;
+}
+
+bool GtkCompositorWidget::WaylandRequestsUpdatingEGLSurface() {
+  bool ret = mWaylandRequestsUpdatingEGLSurface;
+  mWaylandRequestsUpdatingEGLSurface = false;
+  return ret;
+}
+#endif
+
 LayoutDeviceIntSize GtkCompositorWidget::GetClientSize() { return mClientSize; }
 
 uintptr_t GtkCompositorWidget::GetWidgetKey() {
   return reinterpret_cast<uintptr_t>(mWidget);
 }
 
 }  // namespace widget
 }  // namespace mozilla
--- a/widget/gtk/GtkCompositorWidget.h
+++ b/widget/gtk/GtkCompositorWidget.h
@@ -15,16 +15,20 @@ class nsWindow;
 namespace mozilla {
 namespace widget {
 
 class PlatformCompositorWidgetDelegate : public CompositorWidgetDelegate {
  public:
   virtual void NotifyClientSizeChanged(
       const LayoutDeviceIntSize& aClientSize) = 0;
 
+#ifdef MOZ_WAYLAND
+  virtual void RequestsUpdatingEGLSurface() = 0;
+#endif
+
   // CompositorWidgetDelegate Overrides
 
   PlatformCompositorWidgetDelegate* AsPlatformSpecificDelegate() override {
     return this;
   }
 };
 
 class GtkCompositorWidgetInitData;
@@ -57,21 +61,28 @@ class GtkCompositorWidget : public Compo
 
   Display* XDisplay() const { return mXDisplay; }
   Window XWindow() const { return mXWindow; }
 
   // PlatformCompositorWidgetDelegate Overrides
 
   void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) override;
 
+#ifdef MOZ_WAYLAND
+  void RequestsUpdatingEGLSurface() override;
+  bool WaylandRequestsUpdatingEGLSurface();
+#endif
  protected:
   nsWindow* mWidget;
 
  private:
   LayoutDeviceIntSize mClientSize;
+#ifdef MOZ_WAYLAND
+  bool mWaylandRequestsUpdatingEGLSurface = false;
+#endif
 
   Display* mXDisplay;
   Window mXWindow;
   WindowSurfaceProvider mProvider;
 };
 
 }  // namespace widget
 }  // namespace mozilla
--- a/widget/gtk/PCompositorWidget.ipdl
+++ b/widget/gtk/PCompositorWidget.ipdl
@@ -14,16 +14,17 @@ namespace widget {
 sync protocol PCompositorWidget
 {
   manager PCompositorBridge;
 
 parent:
   async __delete__();
 
   async NotifyClientSizeChanged(LayoutDeviceIntSize aClientSize);
+  async RequestsUpdatingEGLSurface();
 
 child:
 
   async ObserveVsync();
   async UnobserveVsync();
 };
 
 } // namespace widget
--- a/widget/gtk/mozcontainer.cpp
+++ b/widget/gtk/mozcontainer.cpp
@@ -155,16 +155,17 @@ void moz_container_init(MozContainer *co
 #if defined(MOZ_WAYLAND)
   container->surface = nullptr;
   container->subsurface = nullptr;
   container->eglwindow = nullptr;
   container->frame_callback_handler = nullptr;
   // We can draw to x11 window any time.
   container->ready_to_draw = GDK_IS_X11_DISPLAY(gdk_display_get_default());
   container->surface_needs_clear = true;
+  container->egl_surface_needs_update = false;
 #endif
 }
 
 #if defined(MOZ_WAYLAND)
 static wl_surface *moz_container_get_gtk_container_surface(
     MozContainer *container) {
   static auto sGdkWaylandWindowGetWlSurface = (wl_surface * (*)(GdkWindow *))
       dlsym(RTLD_DEFAULT, "gdk_wayland_window_get_wl_surface");
@@ -172,16 +173,19 @@ static wl_surface *moz_container_get_gtk
   GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(container));
   return sGdkWaylandWindowGetWlSurface(window);
 }
 
 static void frame_callback_handler(void *data, struct wl_callback *callback,
                                    uint32_t time) {
   MozContainer *container = MOZ_CONTAINER(data);
   g_clear_pointer(&container->frame_callback_handler, wl_callback_destroy);
+  if (!container->ready_to_draw) {
+    container->egl_surface_needs_update = true;
+  }
   container->ready_to_draw = true;
 }
 
 static const struct wl_callback_listener frame_listener = {
     frame_callback_handler};
 
 static gboolean moz_container_map_wayland(GtkWidget *widget,
                                           GdkEventAny *event) {
@@ -205,16 +209,17 @@ static gboolean moz_container_map_waylan
 
 static void moz_container_unmap_wayland(MozContainer *container) {
   g_clear_pointer(&container->eglwindow, wl_egl_window_destroy);
   g_clear_pointer(&container->subsurface, wl_subsurface_destroy);
   g_clear_pointer(&container->surface, wl_surface_destroy);
   g_clear_pointer(&container->frame_callback_handler, wl_callback_destroy);
 
   container->surface_needs_clear = true;
+  container->egl_surface_needs_update = false;
   container->ready_to_draw = false;
 }
 
 static gint moz_container_get_scale(MozContainer *container) {
   static auto sGdkWindowGetScaleFactorPtr =
       (gint(*)(GdkWindow *))dlsym(RTLD_DEFAULT, "gdk_window_get_scale_factor");
 
   if (sGdkWindowGetScaleFactorPtr) {
@@ -550,13 +555,19 @@ gboolean moz_container_has_wl_egl_window
   return container->eglwindow ? true : false;
 }
 
 gboolean moz_container_surface_needs_clear(MozContainer *container) {
   gboolean state = container->surface_needs_clear;
   container->surface_needs_clear = false;
   return state;
 }
+
+gboolean moz_container_egl_surface_needs_update(MozContainer *container){
+  gboolean state = container->egl_surface_needs_update;
+  container->egl_surface_needs_update = false;
+  return state;
+}
 #endif
 
 void moz_container_force_default_visual(MozContainer *container) {
   container->force_default_visual = true;
 }
--- a/widget/gtk/mozcontainer.h
+++ b/widget/gtk/mozcontainer.h
@@ -72,16 +72,17 @@ struct _MozContainer {
   GList *children;
 
 #ifdef MOZ_WAYLAND
   struct wl_surface *surface;
   struct wl_subsurface *subsurface;
   struct wl_egl_window *eglwindow;
   struct wl_callback *frame_callback_handler;
   gboolean surface_needs_clear;
+  gboolean egl_surface_needs_update;
   gboolean ready_to_draw;
 #endif
   gboolean force_default_visual;
 };
 
 struct _MozContainerClass {
   GtkContainerClass parent_class;
 };
@@ -95,11 +96,12 @@ void moz_container_force_default_visual(
 #ifdef MOZ_WAYLAND
 struct wl_surface *moz_container_get_wl_surface(MozContainer *container);
 struct wl_egl_window *moz_container_get_wl_egl_window(MozContainer *container);
 
 gboolean moz_container_has_wl_egl_window(MozContainer *container);
 gboolean moz_container_surface_needs_clear(MozContainer *container);
 void moz_container_scale_changed(MozContainer *container,
                                  GtkAllocation *aAllocation);
+gboolean moz_container_egl_surface_needs_update(MozContainer *container);
 #endif
 
 #endif /* __MOZ_CONTAINER_H__ */
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -1883,16 +1883,21 @@ gboolean nsWindow::OnExposeEvent(cairo_t
     return FALSE;
   }
 
   gint scale = GdkScaleFactor();
   LayoutDeviceIntRegion region = exposeRegion;
   region.ScaleRoundOut(scale, scale);
 
   if (GetLayerManager()->AsKnowsCompositor() && mCompositorSession) {
+#ifdef MOZ_WAYLAND
+    if(mCompositorWidgetDelegate && WaylandRequestsUpdatingEGLSurface()) {
+      mCompositorWidgetDelegate->RequestsUpdatingEGLSurface();
+    }
+#endif
     // We need to paint to the screen even if nothing changed, since if we
     // don't have a compositing window manager, our pixels could be stale.
     GetLayerManager()->SetNeedsComposite(true);
     GetLayerManager()->SendInvalidRegion(region.ToUnknownRegion());
   }
 
   RefPtr<nsWindow> strongThis(this);
 
@@ -6578,16 +6583,27 @@ bool nsWindow::WaylandSurfaceNeedsClear(
   if (mContainer) {
     return moz_container_surface_needs_clear(MOZ_CONTAINER(mContainer));
   }
 
   NS_WARNING(
       "nsWindow::WaylandSurfaceNeedsClear(): We don't have any mContainer!");
   return false;
 }
+
+bool nsWindow::WaylandRequestsUpdatingEGLSurface() {
+  if (mContainer) {
+    return moz_container_egl_surface_needs_update(MOZ_CONTAINER(mContainer));
+  }
+
+  NS_WARNING(
+      "nsWindow::WaylandSurfaceNeedsClear(): We don't have any mContainer!");
+  return false;
+}
+
 #endif
 
 #ifdef MOZ_X11
 /* XApp progress support currently works by setting a property
  * on a window with this Atom name.  A supporting window manager
  * will notice this and pass it along to whatever handling has
  * been implemented on that end (e.g. passing it on to a taskbar
  * widget.)  There is no issue if WM support is lacking, this is
--- a/widget/gtk/nsWindow.h
+++ b/widget/gtk/nsWindow.h
@@ -337,16 +337,17 @@ class nsWindow final : public nsBaseWidg
 
 #ifdef MOZ_X11
   Display* XDisplay() { return mXDisplay; }
 #endif
 #ifdef MOZ_WAYLAND
   wl_display* GetWaylandDisplay();
   wl_surface* GetWaylandSurface();
   bool WaylandSurfaceNeedsClear();
+  bool WaylandRequestsUpdatingEGLSurface();
 #endif
   virtual void GetCompositorWidgetInitData(
       mozilla::widget::CompositorWidgetInitData* aInitData) override;
 
   virtual nsresult SetNonClientMargins(
       LayoutDeviceIntMargin& aMargins) override;
   void SetDrawsInTitlebar(bool aState) override;
   virtual void UpdateWindowDraggingRegion(