commit ac30d4d7974faeacc0816c65d88d75e016979d91
parent f28145d2a08b325bf69ab8d27c7726f0984f9d18
Author: stransky <stransky@redhat.com>
Date: Tue, 6 Jan 2026 19:12:02 +0000
Bug 2001628 [Linux] Make mWindowSurface persistent r=emilio
Right now we create/delete WindowSurface on nsWindow map/unmap event. In this patch we make it persistent
and keep it until nsWindow::Destroy().
Changes:
- Initialize SurfaceProvider at nsWindow::Create() and release at nsWindow::Destroy() so remove ConfigureCompositor/ResumeCompositorImpl() as it's not needed.
- Remove SurfaceProvider::mWindowSurfaceValid as it's always valid (if it's present).
- Start nsWindow VSync source at nsWindow::Create() and stop at nsWindow::Destroy() as we can always paint (even to offscreen / hidden nsWindow).
- Remove nsIWidget::IsMapped() and enable WebRender transaction throttle as we do on other arches - we can always paint now.
- Remove offscreen fallback from GLContextEGL::CreateEGLSurfaceForCompositorWidget() as we always have valid EGLSurface to draw into.
- Set EGLSurface at RenderCompositorEGL::RenderCompositorEGL() instead of fetch at Resume().
- Remove GtkCompositorWidget::SetRenderingSurface() as it's not needed.
- Remove WindowSurfaceProvider mWindowSurface mutex and thread safety hacks.
Differential Revision: https://phabricator.services.mozilla.com/D276964
Diffstat:
17 files changed, 68 insertions(+), 284 deletions(-)
diff --git a/gfx/gl/GLContextProviderEGL.cpp b/gfx/gl/GLContextProviderEGL.cpp
@@ -339,26 +339,8 @@ EGLSurface GLContextEGL::CreateEGLSurfaceForCompositorWidget(
EGLNativeWindowType window =
GET_NATIVE_WINDOW_FROM_COMPOSITOR_WIDGET(aCompositorWidget);
if (!window) {
-#ifdef MOZ_WIDGET_GTK
- // RenderCompositorEGL does not like EGL_NO_SURFACE as it fallbacks
- // to SW rendering or claims itself as paused.
- // In case we're missing valid native window because aCompositorWidget
- // hidden, just create a fallback EGLSurface. Actual EGLSurface will be
- // created by widget code later when aCompositorWidget becomes visible.
- mozilla::gfx::IntSize pbSize(16, 16);
-# ifdef MOZ_WAYLAND
- if (GdkIsWaylandDisplay()) {
- return CreateWaylandOffscreenSurface(*egl, aConfig, pbSize);
- } else
-# endif
- {
- return CreatePBufferSurfaceTryingPowerOfTwo(*egl, aConfig, LOCAL_EGL_NONE,
- pbSize);
- }
-#else
gfxCriticalNote << "window is null";
return EGL_NO_SURFACE;
-#endif
}
return mozilla::gl::CreateSurfaceFromNativeWindow(*egl, window, aConfig);
diff --git a/gfx/layers/wr/WebRenderLayerManager.cpp b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -268,9 +268,8 @@ bool WebRenderLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags) {
mDisplayItemCache.SkipWaitingForPartialDisplayList();
- // Don't block on hidden windows on Linux as it may block all rendering.
- const bool throttle = mWidget->IsMapped();
- mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(throttle);
+ mLatestTransactionId =
+ mTransactionIdAllocator->GetTransactionId(/*aThrottle*/ true);
if (aFlags & EndTransactionFlags::END_NO_COMPOSITE &&
!mWebRenderCommandBuilder.NeedsEmptyTransaction()) {
@@ -421,9 +420,8 @@ void WebRenderLayerManager::EndTransactionWithoutLayer(
// an empty transaction.
ClearAndNotifyOfFullTransactionPendingScrollInfoUpdate();
- // Don't block on hidden windows on Linux as it may block all rendering.
- const bool throttle = mWidget->IsMapped() && !aRenderOffscreen;
- mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(throttle);
+ mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(
+ /*aThrottle*/ !aRenderOffscreen);
// Get the time of when the refresh driver start its tick (if available),
// otherwise use the time of when LayerManager::BeginTransaction was called.
diff --git a/gfx/webrender_bindings/RenderCompositorEGL.cpp b/gfx/webrender_bindings/RenderCompositorEGL.cpp
@@ -72,6 +72,24 @@ RenderCompositorEGL::RenderCompositorEGL(
: RenderCompositor(aWidget), mGL(aGL), mEGLSurface(EGL_NO_SURFACE) {
MOZ_ASSERT(mGL);
LOG("RenderCompositorEGL::RenderCompositorEGL()");
+
+#ifdef MOZ_WIDGET_GTK
+ mEGLSurface = CreateEGLSurface();
+ if (!mEGLSurface) {
+ RenderThread::Get()->HandleWebRenderError(WebRenderError::NEW_SURFACE);
+ return;
+ }
+ // We have a new EGL surface, which on wayland needs to be configured for
+ // non-blocking buffer swaps. We need MakeCurrent() to set our current EGL
+ // context before we call eglSwapInterval, which is why we do it here
+ // rather than where the surface was created.
+ const auto& gle = gl::GLContextEGL::Cast(gl());
+ const auto& egl = gle->mEgl;
+ MakeCurrent();
+
+ const int interval = gfx::gfxVars::SwapIntervalEGL() ? 1 : 0;
+ egl->fSwapInterval(interval);
+#endif
}
RenderCompositorEGL::~RenderCompositorEGL() {
@@ -151,7 +169,7 @@ RenderedFrameId RenderCompositorEGL::EndFrame(
gl()->SetDamage(bufferInvalid);
}
-#ifdef MOZ_WIDGET_GTK
+#ifdef MOZ_WAYLAND
// Rendering on Wayland has to be atomic (buffer attach + commit) and
// wayland surface is also used by main thread so lock it before
// we paint at SwapBuffers().
@@ -164,7 +182,11 @@ RenderedFrameId RenderCompositorEGL::EndFrame(
return frameId;
}
-void RenderCompositorEGL::Pause() { DestroyEGLSurface(); }
+void RenderCompositorEGL::Pause() {
+ if (kIsAndroid) {
+ DestroyEGLSurface();
+ }
+}
bool RenderCompositorEGL::Resume() {
if (kIsAndroid) {
@@ -202,31 +224,17 @@ bool RenderCompositorEGL::Resume() {
mHandlingNewSurfaceError = false;
gl::GLContextEGL::Cast(gl())->SetEGLSurfaceOverride(mEGLSurface);
- } else if (kIsLinux) {
- // Destroy EGLSurface if it exists and create a new one. We will set the
- // swap interval after MakeCurrent() has been called.
- DestroyEGLSurface();
- mEGLSurface = CreateEGLSurface();
- if (mEGLSurface != EGL_NO_SURFACE) {
- // We have a new EGL surface, which on wayland needs to be configured for
- // non-blocking buffer swaps. We need MakeCurrent() to set our current EGL
- // context before we call eglSwapInterval, which is why we do it here
- // rather than where the surface was created.
- const auto& gle = gl::GLContextEGL::Cast(gl());
- const auto& egl = gle->mEgl;
- MakeCurrent();
-
- const int interval = gfx::gfxVars::SwapIntervalEGL() ? 1 : 0;
- egl->fSwapInterval(interval);
- } else {
- RenderThread::Get()->HandleWebRenderError(WebRenderError::NEW_SURFACE);
- return false;
- }
}
return true;
}
-bool RenderCompositorEGL::IsPaused() { return mEGLSurface == EGL_NO_SURFACE; }
+bool RenderCompositorEGL::IsPaused() {
+#ifdef MOZ_WIDGET_ANDROID
+ return mEGLSurface == EGL_NO_SURFACE;
+#else
+ return false;
+#endif
+}
bool RenderCompositorEGL::MakeCurrent() {
const auto& gle = gl::GLContextEGL::Cast(gl());
diff --git a/gfx/webrender_bindings/RenderCompositorOGLSWGL.cpp b/gfx/webrender_bindings/RenderCompositorOGLSWGL.cpp
@@ -218,8 +218,6 @@ bool RenderCompositorOGLSWGL::RequestFullRender() { return mFullRender; }
void RenderCompositorOGLSWGL::Pause() {
#ifdef MOZ_WIDGET_ANDROID
DestroyEGLSurface();
-#elif defined(MOZ_WIDGET_GTK)
- mCompositor->Pause();
#endif
}
@@ -261,12 +259,6 @@ bool RenderCompositorOGLSWGL::Resume() {
gl::GLContextEGL::Cast(GetGLContext())->SetEGLSurfaceOverride(mEGLSurface);
mCompositor->SetDestinationSurfaceSize(size.ToUnknownSize());
-#elif defined(MOZ_WIDGET_GTK)
- bool resumed = mCompositor->Resume();
- if (!resumed) {
- RenderThread::Get()->HandleWebRenderError(WebRenderError::NEW_SURFACE);
- return false;
- }
#endif
return true;
}
diff --git a/gfx/webrender_bindings/RenderCompositorSWGL.cpp b/gfx/webrender_bindings/RenderCompositorSWGL.cpp
@@ -78,10 +78,8 @@ bool RenderCompositorSWGL::AllocateMappedBuffer(
MOZ_ASSERT(!mDT);
mDT = mWidget->StartRemoteDrawingInRegion(mDirtyRegion);
if (!mDT) {
-#if !defined(MOZ_WAYLAND)
gfxCriticalNoteOnce
<< "RenderCompositorSWGL failed mapping default framebuffer, no dt";
-#endif
return false;
}
// Attempt to lock the underlying buffer directly from the draw target.
diff --git a/widget/gtk/CompositorWidgetChild.cpp b/widget/gtk/CompositorWidgetChild.cpp
@@ -43,9 +43,5 @@ void CompositorWidgetChild::NotifyClientSizeChanged(
void CompositorWidgetChild::CleanupResources() { (void)SendCleanupResources(); }
-void CompositorWidgetChild::SetRenderingSurface(const uintptr_t aXWindow) {
- (void)SendSetRenderingSurface(aXWindow);
-}
-
} // namespace widget
} // namespace mozilla
diff --git a/widget/gtk/CompositorWidgetChild.h b/widget/gtk/CompositorWidgetChild.h
@@ -30,7 +30,6 @@ class CompositorWidgetChild final : public PCompositorWidgetChild,
void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) override;
void NotifyFullscreenChanged(bool aIsFullscreen) override {};
void CleanupResources() override;
- void SetRenderingSurface(const uintptr_t aXWindow) override;
private:
~CompositorWidgetChild() override;
diff --git a/widget/gtk/CompositorWidgetParent.cpp b/widget/gtk/CompositorWidgetParent.cpp
@@ -44,10 +44,4 @@ mozilla::ipc::IPCResult CompositorWidgetParent::RecvCleanupResources() {
return IPC_OK();
}
-mozilla::ipc::IPCResult CompositorWidgetParent::RecvSetRenderingSurface(
- const uintptr_t& aXWindow) {
- SetRenderingSurface(aXWindow);
- return IPC_OK();
-}
-
} // namespace mozilla::widget
diff --git a/widget/gtk/CompositorWidgetParent.h b/widget/gtk/CompositorWidgetParent.h
@@ -30,8 +30,6 @@ class CompositorWidgetParent final : public PCompositorWidgetParent,
const LayoutDeviceIntSize& aClientSize) override;
mozilla::ipc::IPCResult RecvCleanupResources() override;
- mozilla::ipc::IPCResult RecvSetRenderingSurface(
- const uintptr_t& aXWindow) override;
private:
~CompositorWidgetParent() override;
diff --git a/widget/gtk/GtkCompositorWidget.cpp b/widget/gtk/GtkCompositorWidget.cpp
@@ -181,23 +181,6 @@ void GtkCompositorWidget::ConfigureX11Backend(Window aXWindow) {
}
#endif
-void GtkCompositorWidget::SetRenderingSurface(const uintptr_t aXWindow) {
- LOG("GtkCompositorWidget::SetRenderingSurface() [%p]\n", mWidget.get());
-
-#if defined(MOZ_WAYLAND)
- if (GdkIsWaylandDisplay()) {
- LOG(" configure widget %p\n", mWidget.get());
- ConfigureWaylandBackend();
- }
-#endif
-#if defined(MOZ_X11)
- if (GdkIsX11Display()) {
- LOG(" configure XWindow %p\n", (void*)aXWindow);
- ConfigureX11Backend((Window)aXWindow);
- }
-#endif
-}
-
#ifdef MOZ_LOGGING
bool GtkCompositorWidget::IsPopup() {
return mWidget ? mWidget->IsPopup() : false;
diff --git a/widget/gtk/GtkCompositorWidget.h b/widget/gtk/GtkCompositorWidget.h
@@ -32,7 +32,6 @@ class PlatformCompositorWidgetDelegate : public CompositorWidgetDelegate {
virtual GtkCompositorWidget* AsGtkCompositorWidget() { return nullptr; };
virtual void CleanupResources() = 0;
- virtual void SetRenderingSurface(const uintptr_t aXWindow) = 0;
// CompositorWidgetDelegate Overrides
@@ -76,9 +75,6 @@ class GtkCompositorWidget : public CompositorWidget,
// Can be used when underlying window is hidden/unmapped.
void CleanupResources() override;
- // Resume rendering with to given aXWindow (X11) or nsWindow (Wayland).
- void SetRenderingSurface(const uintptr_t aXWindow) override;
-
// Set EGLWindow size to avoid rendering artifacts
void SetEGLNativeWindowSize(const LayoutDeviceIntSize& aEGLWindowSize);
diff --git a/widget/gtk/PCompositorWidget.ipdl b/widget/gtk/PCompositorWidget.ipdl
@@ -23,7 +23,6 @@ parent:
async NotifyClientSizeChanged(LayoutDeviceIntSize aClientSize);
async CleanupResources();
- async SetRenderingSurface(uintptr_t aXWindow);
child:
diff --git a/widget/gtk/WindowSurfaceProvider.cpp b/widget/gtk/WindowSurfaceProvider.cpp
@@ -11,7 +11,6 @@
#include "mozilla/gfx/Logging.h"
#include "mozilla/layers/LayersTypes.h"
#include "nsWindow.h"
-#include "mozilla/ScopeExit.h"
#include "WidgetUtilsGtk.h"
#ifdef MOZ_WAYLAND
@@ -42,9 +41,7 @@ namespace widget {
using namespace mozilla::layers;
WindowSurfaceProvider::WindowSurfaceProvider()
- : mWindowSurface(nullptr),
- mMutex("WindowSurfaceProvider"),
- mWindowSurfaceValid(false)
+ : mWindowSurface(nullptr)
#ifdef MOZ_X11
,
mXDepth(0),
@@ -66,12 +63,10 @@ WindowSurfaceProvider::~WindowSurfaceProvider() {
#ifdef MOZ_WAYLAND
bool WindowSurfaceProvider::Initialize(RefPtr<nsWindow> aWidget) {
- mWindowSurfaceValid = false;
mWidget = std::move(aWidget);
return true;
}
bool WindowSurfaceProvider::Initialize(GtkCompositorWidget* aCompositorWidget) {
- mWindowSurfaceValid = false;
mCompositorWidget = aCompositorWidget;
mWidget = static_cast<nsWindow*>(aCompositorWidget->RealWidget());
return true;
@@ -79,8 +74,6 @@ bool WindowSurfaceProvider::Initialize(GtkCompositorWidget* aCompositorWidget) {
#endif
#ifdef MOZ_X11
bool WindowSurfaceProvider::Initialize(Window aWindow) {
- mWindowSurfaceValid = false;
-
// Grab the window's visual and depth
XWindowAttributes windowAttrs;
if (!XGetWindowAttributes(DefaultXDisplay(), aWindow, &windowAttrs)) {
@@ -96,8 +89,6 @@ bool WindowSurfaceProvider::Initialize(Window aWindow) {
#endif
void WindowSurfaceProvider::CleanupResources() {
- MutexAutoLock lock(mMutex);
- mWindowSurfaceValid = false;
#ifdef MOZ_WAYLAND
mWidget = nullptr;
#endif
@@ -146,11 +137,6 @@ RefPtr<WindowSurface> WindowSurfaceProvider::CreateWindowSurface() {
MOZ_RELEASE_ASSERT(false);
}
-// We need to ignore thread safety checks here. We need to hold mMutex
-// between StartRemoteDrawingInRegion()/EndRemoteDrawingInRegion() calls
-// which confuses it.
-MOZ_PUSH_IGNORE_THREAD_SAFETY
-
already_AddRefed<gfx::DrawTarget>
WindowSurfaceProvider::StartRemoteDrawingInRegion(
const LayoutDeviceIntRegion& aInvalidRegion) {
@@ -158,19 +144,6 @@ WindowSurfaceProvider::StartRemoteDrawingInRegion(
return nullptr;
}
- // We return a reference to mWindowSurface inside draw target so we need to
- // hold the mutex untill EndRemoteDrawingInRegion() call where draw target
- // is returned.
- // If we return null dt, EndRemoteDrawingInRegion() won't be called to
- // release mutex.
- mMutex.Lock();
- auto unlockMutex = MakeScopeExit([&] { mMutex.Unlock(); });
-
- if (!mWindowSurfaceValid) {
- mWindowSurface = nullptr;
- mWindowSurfaceValid = true;
- }
-
if (!mWindowSurface) {
mWindowSurface = CreateWindowSurface();
if (!mWindowSurface) {
@@ -190,37 +163,13 @@ WindowSurfaceProvider::StartRemoteDrawingInRegion(
dt = mWindowSurface->Lock(aInvalidRegion);
}
#endif
- if (dt) {
- // We have valid dt, mutex will be released in EndRemoteDrawingInRegion().
- unlockMutex.release();
- }
-
return dt.forget();
}
void WindowSurfaceProvider::EndRemoteDrawingInRegion(
gfx::DrawTarget* aDrawTarget, const LayoutDeviceIntRegion& aInvalidRegion) {
- // Unlock mutex from StartRemoteDrawingInRegion().
- mMutex.AssertCurrentThreadOwns();
- auto unlockMutex = MakeScopeExit([&] { mMutex.Unlock(); });
-
- // Commit to mWindowSurface only if we have a valid one.
- if (!mWindowSurface || !mWindowSurfaceValid) {
- return;
- }
-#if defined(MOZ_WAYLAND)
- if (GdkIsWaylandDisplay()) {
- // We're called too early or we're unmapped.
- // Don't draw anything.
- if (!mWidget || !mWidget->IsMapped()) {
- return;
- }
- }
-#endif
mWindowSurface->Commit(aInvalidRegion);
}
-MOZ_POP_THREAD_SAFETY
-
} // namespace widget
} // namespace mozilla
diff --git a/widget/gtk/WindowSurfaceProvider.h b/widget/gtk/WindowSurfaceProvider.h
@@ -70,16 +70,6 @@ class WindowSurfaceProvider final {
RefPtr<WindowSurface> mWindowSurface;
- /* While CleanupResources() can be called from Main thread when nsWindow is
- * destroyed/hidden, StartRemoteDrawingInRegion()/EndRemoteDrawingInRegion()
- * is called from Compositor thread during rendering.
- *
- * As nsWindow CleanupResources() call comes from Gtk/X11 we can't synchronize
- * that with WebRender so we use lock to synchronize the access.
- */
- mozilla::Mutex mMutex MOZ_UNANNOTATED;
- // WindowSurface needs to be re-created as underlying window was changed.
- bool mWindowSurfaceValid;
#ifdef MOZ_WAYLAND
RefPtr<nsWindow> mWidget;
// WindowSurfaceProvider is owned by GtkCompositorWidget so we don't need
@@ -88,12 +78,7 @@ class WindowSurfaceProvider final {
#endif
#ifdef MOZ_X11
int mXDepth;
- // Make mXWindow atomic to allow it read from different threads
- // and make tsan happy.
- // We don't care much about actual mXWindow value (it may be valid XWindow or
- // nullptr) because we invalidate mXWindow at compositor/renderer thread
- // before it's release in unmap handler.
- Atomic<Window, Relaxed> mXWindow;
+ Window mXWindow;
Visual* mXVisual;
#endif
};
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
@@ -859,8 +859,6 @@ void nsWindow::SetModal(bool aModal) {
// nsIWidget method, which means IsShown.
bool nsWindow::IsVisible() const { return mIsShown; }
-bool nsWindow::IsMapped() const { return mIsMapped; }
-
void nsWindow::RegisterTouchWindow() {
mHandleTouchEvent = true;
mTouches.Clear();
@@ -1398,7 +1396,6 @@ void nsWindow::HideWaylandToplevelWindow() {
popup = prev;
}
}
- WaylandStopVsync();
gtk_widget_hide(mShell);
}
@@ -6082,22 +6079,6 @@ Window nsWindow::GetX11Window() {
return (Window) nullptr;
}
-void nsWindow::ConfigureCompositor() {
- LOG("nsWindow::ConfigureCompositor()");
-
- if (mIsDestroyed) {
- LOG(" quit, mIsDestroyed = %d", !!mIsDestroyed);
- return;
- }
- // Compositor will be resumed at nsWindow::SetCompositorWidgetDelegate().
- if (!mCompositorWidgetDelegate) {
- LOG(" quit, missing mCompositorWidgetDelegate");
- return;
- }
-
- ResumeCompositorImpl();
-}
-
void nsWindow::SetGdkWindow(GdkWindow* aGdkWindow) {
LOG("nsWindow::SetGdkWindow() %p", aGdkWindow);
if (!aGdkWindow) {
@@ -6361,6 +6342,8 @@ nsresult nsWindow::Create(nsIWidget* aParent, const LayoutDeviceIntRect& aRect,
}
gtk_widget_realize(container);
+ // mGdkWindow is set by moz_container_realize() / SetGdkWindow().
+ MOZ_DIAGNOSTIC_ASSERT(mGdkWindow, "MozContainer realize failed?");
#ifdef MOZ_X11
if (GdkIsX11Display()) {
@@ -6369,7 +6352,7 @@ nsresult nsWindow::Create(nsIWidget* aParent, const LayoutDeviceIntRect& aRect,
#endif
#ifdef MOZ_WAYLAND
if (GdkIsWaylandDisplay() && mIsAccelerated) {
- mEGLWindow = MOZ_WL_SURFACE(container)->GetEGLWindow(mClientArea.Size());
+ mEGLWindow = mSurface->GetEGLWindow(mClientArea.Size());
}
#endif
if (mEGLWindow) {
@@ -6377,6 +6360,24 @@ nsresult nsWindow::Create(nsIWidget* aParent, const LayoutDeviceIntRect& aRect,
mGdkWindow, mEGLWindow);
}
+#ifdef MOZ_X11
+ if (GdkIsX11Display()) {
+ mSurfaceProvider.Initialize(GetX11Window());
+
+ // Set window manager hint to keep fullscreen windows composited.
+ //
+ // If the window were to get unredirected, there could be visible
+ // tearing because Gecko does not align its framebuffer updates with
+ // vblank.
+ SetCompositorHint(GTK_WIDGET_COMPOSITED_ENABLED);
+ }
+#endif
+#ifdef MOZ_WAYLAND
+ if (GdkIsWaylandDisplay()) {
+ mSurfaceProvider.Initialize(this);
+ }
+#endif
+
// make sure this is the focus widget in the container
gtk_widget_show(container);
@@ -6507,6 +6508,7 @@ nsresult nsWindow::Create(nsIWidget* aParent, const LayoutDeviceIntRect& aRect,
mWaylandVsyncSource = new WaylandVsyncSource(this);
mWaylandVsyncSource->Init();
mWaylandVsyncDispatcher = new VsyncDispatcher(mWaylandVsyncSource);
+ mWaylandVsyncSource->EnableVSyncSource();
}
#endif
@@ -6791,44 +6793,6 @@ void nsWindow::NativeMoveResize(bool aMoved, bool aResized) {
}
}
-void nsWindow::ResumeCompositorImpl() {
- MOZ_RELEASE_ASSERT(NS_IsMainThread());
-
- LOG("nsWindow::ResumeCompositorImpl()\n");
-
- MOZ_DIAGNOSTIC_ASSERT(mCompositorWidgetDelegate);
- mCompositorWidgetDelegate->SetRenderingSurface(GetX11Window());
-
- // As WaylandStartVsync needs mCompositorWidgetDelegate this is the right
- // time to start it.
- WaylandStartVsync();
-
- CompositorBridgeChild* remoteRenderer = GetRemoteRenderer();
- MOZ_RELEASE_ASSERT(remoteRenderer);
- remoteRenderer->SendResume();
- remoteRenderer->SendForcePresent(wr::RenderReasons::WIDGET);
-}
-
-void nsWindow::WaylandStartVsync() {
-#ifdef MOZ_WAYLAND
- if (!mWaylandVsyncSource) {
- return;
- }
- LOG_VSYNC("nsWindow::WaylandStartVsync");
- mWaylandVsyncSource->EnableVSyncSource();
-#endif
-}
-
-void nsWindow::WaylandStopVsync() {
-#ifdef MOZ_WAYLAND
- if (!mWaylandVsyncSource) {
- return;
- }
- LOG_VSYNC("nsWindow::WaylandStopVsync");
- mWaylandVsyncSource->DisableVSyncSource();
-#endif
-}
-
void nsWindow::NativeShow(bool aAction) {
if (aAction) {
// unset our flag now that our window has been shown
@@ -8933,17 +8897,8 @@ void nsWindow::SetCompositorWidgetDelegate(CompositorWidgetDelegate* delegate) {
delegate, !!mIsMapped, mCompositorWidgetDelegate);
MOZ_RELEASE_ASSERT(NS_IsMainThread());
- if (delegate) {
- mCompositorWidgetDelegate = delegate->AsPlatformSpecificDelegate();
- MOZ_ASSERT(mCompositorWidgetDelegate,
- "nsWindow::SetCompositorWidgetDelegate called with a "
- "non-PlatformCompositorWidgetDelegate");
- if (mIsMapped) {
- ConfigureCompositor();
- }
- } else {
- mCompositorWidgetDelegate = nullptr;
- }
+ mCompositorWidgetDelegate =
+ delegate ? delegate->AsPlatformSpecificDelegate() : nullptr;
}
bool nsWindow::IsAlwaysUndecoratedWindow() const {
@@ -9517,24 +9472,11 @@ nsWindow::GtkWindowDecoration nsWindow::GetSystemGtkWindowDecoration() {
void nsWindow::GetCompositorWidgetInitData(
mozilla::widget::CompositorWidgetInitData* aInitData) {
- nsCString displayName;
+ MOZ_DIAGNOSTIC_ASSERT(!mIsDestroyed);
LOG("nsWindow::GetCompositorWidgetInitData");
- Window window = GetX11Window();
-#ifdef MOZ_X11
- // We're bit hackish here. Old GLX backend needs XWindow when GLContext
- // is created so get XWindow now before map signal.
- // We may see crashes/errors when nsWindow is unmapped (XWindow is
- // invalidated) but we can't do anything about it.
- if (!window && !gfxVars::UseEGL()) {
- window =
- gdk_x11_window_get_xid(gtk_widget_get_window(GTK_WIDGET(mContainer)));
- }
-#endif
- *aInitData = mozilla::widget::GtkCompositorWidgetInitData(
- window, displayName, GdkIsX11Display(), GetClientSize());
-
+ nsCString displayName;
#ifdef MOZ_X11
if (GdkIsX11Display()) {
// Make sure the window XID is propagated to X server, we can fail otherwise
@@ -9544,6 +9486,9 @@ void nsWindow::GetCompositorWidgetInitData(
displayName = nsCString(XDisplayString(display));
}
#endif
+
+ *aInitData = mozilla::widget::GtkCompositorWidgetInitData(
+ GetX11Window(), displayName, GdkIsX11Display(), GetClientSize());
}
#ifdef MOZ_X11
@@ -9831,24 +9776,6 @@ void nsWindow::OnMap() {
if (mIsAlert) {
gdk_window_set_override_redirect(GetToplevelGdkWindow(), TRUE);
}
-
-#ifdef MOZ_X11
- if (GdkIsX11Display()) {
- mSurfaceProvider.Initialize(GetX11Window());
-
- // Set window manager hint to keep fullscreen windows composited.
- //
- // If the window were to get unredirected, there could be visible
- // tearing because Gecko does not align its framebuffer updates with
- // vblank.
- SetCompositorHint(GTK_WIDGET_COMPOSITED_ENABLED);
- }
-#endif
-#ifdef MOZ_WAYLAND
- if (GdkIsWaylandDisplay()) {
- mSurfaceProvider.Initialize(this);
- }
-#endif
}
if (mIsDragPopup && GdkIsX11Display()) {
@@ -9864,12 +9791,7 @@ void nsWindow::OnMap() {
RefreshWindowClass();
- // We're not mapped yet but we have already created compositor.
- if (mCompositorWidgetDelegate) {
- ConfigureCompositor();
- }
-
- LOG(" finished, new GdkWindow %p XID 0x%lx\n", mGdkWindow, GetX11Window());
+ LOG(" finished, GdkWindow %p XID 0x%lx\n", mGdkWindow, GetX11Window());
}
void nsWindow::OnUnmap() {
diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h
@@ -194,7 +194,6 @@ class nsWindow final : public nsIWidget {
mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() override;
void SetModal(bool aModal) override;
bool IsVisible() const override;
- bool IsMapped() const override;
void ConstrainPosition(DesktopIntPoint&) override;
void SetSizeConstraints(const SizeConstraints&) override;
void LockAspectRatio(bool aShouldLock) override;
@@ -531,8 +530,6 @@ class nsWindow final : public nsIWidget {
LayoutDeviceIntSize GetMoveToRectPopupSize() override;
#endif
- void ResumeCompositorImpl();
-
bool ApplyEnterLeaveMutterWorkaround();
void NotifyOcclusionState(mozilla::widget::OcclusionState aState) override;
@@ -577,8 +574,6 @@ class nsWindow final : public nsIWidget {
bool DoTitlebarAction(mozilla::LookAndFeel::TitlebarEvent aEvent,
GdkEventButton* aButtonEvent);
- void WaylandStartVsync();
- void WaylandStopVsync();
void DestroyChildWindows();
GtkWidget* GetToplevelWidget() const;
nsWindow* GetContainerWindow() const;
@@ -716,7 +711,7 @@ class nsWindow final : public nsIWidget {
// This track real window visibility from OS perspective.
// It's set by OnMap/OnUnmap which is based on Gtk events.
- mozilla::Atomic<bool, mozilla::Relaxed> mIsMapped;
+ bool mIsMapped;
// Has this widget been destroyed yet?
mozilla::Atomic<bool, mozilla::Relaxed> mIsDestroyed;
// mIsShown tracks requested visible status from browser perspective, i.e.
@@ -871,8 +866,6 @@ class nsWindow final : public nsIWidget {
void DispatchMissedButtonReleases(GdkEventCrossing* aGdkEvent);
- void ConfigureCompositor();
-
bool IsAlwaysUndecoratedWindow() const;
// nsIWidget
diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h
@@ -727,14 +727,6 @@ class nsIWidget : public nsSupportsWeakReference {
virtual bool IsVisible() const = 0;
/**
- * Returns whether the window has allocated resources so
- * we can paint into it.
- * Recently it's used on Linux/Gtk where we should not paint
- * to invisible window.
- */
- virtual bool IsMapped() const { return true; }
-
- /**
* Perform platform-dependent sanity check on a potential window position.
* This is guaranteed to work only for top-level windows.
*/