diff --git a/gfx/webrender_bindings/RenderCompositorEGL.cpp b/gfx/webrender_bindings/RenderCompositorEGL.cpp --- a/gfx/webrender_bindings/RenderCompositorEGL.cpp +++ b/gfx/webrender_bindings/RenderCompositorEGL.cpp @@ -154,6 +154,13 @@ RenderedFrameId RenderCompositorEGL::End } gl()->SetDamage(bufferInvalid); } + +#ifdef MOZ_WIDGET_GTK + UniquePtr lock; + if (mWidget->AsGTK()) { + lock = mWidget->AsGTK()->LockSurface(); + } +#endif gl()->SwapBuffers(); return frameId; } diff --git a/widget/gtk/GtkCompositorWidget.cpp b/widget/gtk/GtkCompositorWidget.cpp --- a/widget/gtk/GtkCompositorWidget.cpp +++ b/widget/gtk/GtkCompositorWidget.cpp @@ -211,5 +211,11 @@ bool GtkCompositorWidget::IsPopup() { } #endif +#if defined(MOZ_WAYLAND) +UniquePtr GtkCompositorWidget::LockSurface() { + return mWidget->LockSurface(); +} +#endif + } // namespace widget } // namespace mozilla diff --git a/widget/gtk/GtkCompositorWidget.h b/widget/gtk/GtkCompositorWidget.h --- a/widget/gtk/GtkCompositorWidget.h +++ b/widget/gtk/GtkCompositorWidget.h @@ -10,6 +10,10 @@ #include "mozilla/DataMutex.h" #include "mozilla/widget/CompositorWidget.h" #include "WindowSurfaceProvider.h" +#if defined(MOZ_WAYLAND) +# include "mozilla/UniquePtr.h" +# include "MozContainerSurfaceLock.h" +#endif class nsIWidget; class nsWindow; @@ -96,6 +100,8 @@ class GtkCompositorWidget : public Compo void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) override; GtkCompositorWidget* AsGtkCompositorWidget() override { return this; } + UniquePtr LockSurface(); + private: #if defined(MOZ_WAYLAND) void ConfigureWaylandBackend(); diff --git a/widget/gtk/MozContainerSurfaceLock.cpp b/widget/gtk/MozContainerSurfaceLock.cpp new file mode 100644 --- /dev/null +++ b/widget/gtk/MozContainerSurfaceLock.cpp @@ -0,0 +1,27 @@ +/* -*- 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 "MozContainerSurfaceLock.h" +#include "MozContainer.h" +#include "WidgetUtilsGtk.h" + +MozContainerSurfaceLock::MozContainerSurfaceLock(MozContainer* aContainer) { + mContainer = aContainer; +#ifdef MOZ_WAYLAND + if (GdkIsWaylandDisplay()) { + mSurface = moz_container_wayland_surface_lock(aContainer); + } +#endif +} + +MozContainerSurfaceLock::~MozContainerSurfaceLock() { +#ifdef MOZ_WAYLAND + if (GdkIsWaylandDisplay()) { + moz_container_wayland_surface_unlock(mContainer, &mSurface); + } +#endif +} + +struct wl_surface* MozContainerSurfaceLock::GetSurface() { return mSurface; } diff --git a/widget/gtk/MozContainerSurfaceLock.h b/widget/gtk/MozContainerSurfaceLock.h new file mode 100644 --- /dev/null +++ b/widget/gtk/MozContainerSurfaceLock.h @@ -0,0 +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_MozContainerSurfaceLock_h +#define widget_gtk_MozContainerSurfaceLock_h + +struct wl_surface; +struct _MozContainer; +typedef struct _MozContainer MozContainer; + +class MozContainerSurfaceLock { + public: + explicit MozContainerSurfaceLock(MozContainer* aContainer); + ~MozContainerSurfaceLock(); + + struct wl_surface* GetSurface(); + + private: + MozContainer* mContainer = nullptr; + struct wl_surface* mSurface = nullptr; +}; + +#endif // widget_gtk_MozContainerSurfaceLock_h diff --git a/widget/gtk/MozContainerWayland.cpp b/widget/gtk/MozContainerWayland.cpp --- a/widget/gtk/MozContainerWayland.cpp +++ b/widget/gtk/MozContainerWayland.cpp @@ -87,23 +87,6 @@ static void moz_container_wayland_set_op const MutexAutoLock& aProofOfLock, MozContainer* container, const LayoutDeviceIntRegion&); -// Lock mozcontainer and get wayland surface of it. You need to pair with -// moz_container_wayland_surface_unlock() even -// if moz_container_wayland_surface_lock() fails and returns nullptr. -static struct wl_surface* moz_container_wayland_surface_lock( - MozContainer* container); -static void moz_container_wayland_surface_unlock(MozContainer* container, - struct wl_surface** surface); - -MozContainerSurfaceLock::MozContainerSurfaceLock(MozContainer* aContainer) { - mContainer = aContainer; - mSurface = moz_container_wayland_surface_lock(aContainer); -} -MozContainerSurfaceLock::~MozContainerSurfaceLock() { - moz_container_wayland_surface_unlock(mContainer, &mSurface); -} -struct wl_surface* MozContainerSurfaceLock::GetSurface() { return mSurface; } - // Invalidate gtk wl_surface to commit changes to wl_subsurface. // wl_subsurface changes are effective when parent surface is commited. static void moz_container_wayland_invalidate(MozContainer* container) { diff --git a/widget/gtk/MozContainerWayland.h b/widget/gtk/MozContainerWayland.h --- a/widget/gtk/MozContainerWayland.h +++ b/widget/gtk/MozContainerWayland.h @@ -13,6 +13,7 @@ #include #include "mozilla/Mutex.h" #include "WindowSurface.h" +#include "MozContainerSurfaceLock.h" /* * MozContainer @@ -61,15 +62,12 @@ struct _MozContainerClass; typedef struct _MozContainer MozContainer; typedef struct _MozContainerClass MozContainerClass; -class MozContainerSurfaceLock { - MozContainer* mContainer; - struct wl_surface* mSurface; - - public: - explicit MozContainerSurfaceLock(MozContainer* aContainer); - ~MozContainerSurfaceLock(); - struct wl_surface* GetSurface(); -}; +// Lock mozcontainer and get wayland surface of it. You need to pair with +// moz_container_wayland_surface_unlock() even +// if moz_container_wayland_surface_lock() fails and returns nullptr. +struct wl_surface* moz_container_wayland_surface_lock(MozContainer* container); +void moz_container_wayland_surface_unlock(MozContainer* container, + struct wl_surface** surface); void moz_container_wayland_map(GtkWidget*); gboolean moz_container_wayland_map_event(GtkWidget*, GdkEventAny*); diff --git a/widget/gtk/moz.build b/widget/gtk/moz.build --- a/widget/gtk/moz.build +++ b/widget/gtk/moz.build @@ -33,6 +33,7 @@ if CONFIG["MOZ_ENABLE_V4L2"]: EXPORTS += [ "MozContainer.h", + "MozContainerSurfaceLock.h", "nsGTKToolkit.h", "nsGtkUtils.h", "nsImageToPixbuf.h", @@ -71,6 +72,7 @@ UNIFIED_SOURCES += [ "IMContextWrapper.cpp", "InProcessGtkCompositorWidget.cpp", "MozContainer.cpp", + "MozContainerSurfaceLock.cpp", "MPRISServiceHandler.cpp", "NativeKeyBindings.cpp", "NativeMenuGtk.cpp", @@ -114,6 +116,7 @@ if CONFIG["MOZ_WAYLAND"]: "WindowSurfaceWaylandMultiBuffer.cpp", ] EXPORTS.mozilla.widget += [ + "MozContainerSurfaceLock.h", "MozContainerWayland.h", "nsWaylandDisplay.h", "WaylandBuffer.h", diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -10196,3 +10196,10 @@ void nsWindow::SetDragSource(GdkDragCont } } } + +UniquePtr nsWindow::LockSurface() { + if (mIsDestroyed) { + return nullptr; + } + return MakeUnique(mContainer); +} diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -42,6 +42,7 @@ # include "base/thread.h" # include "WaylandVsyncSource.h" # include "nsClipboardWayland.h" +# include "MozContainerSurfaceLock.h" #endif #ifdef MOZ_LOGGING @@ -421,6 +422,8 @@ class nsWindow final : public nsBaseWidg static nsWindow* GetFocusedWindow(); + mozilla::UniquePtr LockSurface(); + #ifdef MOZ_WAYLAND // Use xdg-activation protocol to transfer focus from gFocusWindow to aWindow. static void TransferFocusToWaylandWindow(nsWindow* aWindow);