From 7bf72f012c76e1112a9cdc0858636539febb8604 Mon Sep 17 00:00:00 2001 From: Martin Stransky Date: Tue, 6 Oct 2020 12:00:47 +0200 Subject: [PATCH] Added fix for mozbz#1656727 --- firefox.spec | 10 +- mozilla-1656727.patch | 208 ++++++++++++++++++++++++++++++++++++++++++ pgo.patch | 1 + 3 files changed, 217 insertions(+), 2 deletions(-) create mode 100644 mozilla-1656727.patch diff --git a/firefox.spec b/firefox.spec index 42922ae..5e0e45f 100644 --- a/firefox.spec +++ b/firefox.spec @@ -110,7 +110,7 @@ ExcludeArch: s390x Summary: Mozilla Firefox Web browser Name: firefox Version: 81.0.1 -Release: 4%{?dist} +Release: 5%{?dist} URL: https://www.mozilla.org/firefox/ License: MPLv1.1 or GPLv2+ or LGPLv2+ Source0: https://archive.mozilla.org/pub/firefox/releases/%{version}%{?pre_version}/source/firefox-%{version}%{?pre_version}.source.tar.xz @@ -179,6 +179,7 @@ Patch408: mozilla-1663844.patch Patch409: mozilla-1640567.patch Patch410: mozilla-1661192.patch Patch411: mozilla-1668771.patch +Patch412: mozilla-1656727.patch # Wayland specific upstream patches Patch574: firefox-pipewire-0-2.patch @@ -391,6 +392,7 @@ This package contains results of tests executed during build. %patch409 -p1 -b .1640567 %patch410 -p1 -b .1661192 %patch411 -p1 -b .1668771 +%patch412 -p1 -b .1656727 # Wayland specific upstream patches %if 0%{?fedora} < 32 @@ -623,7 +625,8 @@ echo "export RANLIB=\"gcc-ranlib\"" >> .mozconfig %endif %if 0%{?build_with_pgo} echo "ac_add_options MOZ_PGO=1" >> .mozconfig -#echo "ac_add_options --enable-lto" >> .mozconfig +# Temporary disabled due to https://bugzilla.mozilla.org/show_bug.cgi?id=1669442 +# echo "ac_add_options --enable-lto" >> .mozconfig # PGO build doesn't work with ccache export CCACHE_DISABLE=1 %endif @@ -980,6 +983,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : #--------------------------------------------------------------------- %changelog +* Mon Oct 5 2020 Martin Stransky - 81.0.1-5 +- Added fix for mozbz#1656727 + * Fri Oct 2 2020 Martin Stransky - 81.0.1-4 - Added fix for mozbz#1668771 diff --git a/mozilla-1656727.patch b/mozilla-1656727.patch new file mode 100644 index 0000000..3631e8c --- /dev/null +++ b/mozilla-1656727.patch @@ -0,0 +1,208 @@ +diff -up firefox-81.0.1/widget/gtk/WindowSurfaceWayland.cpp.1656727 firefox-81.0.1/widget/gtk/WindowSurfaceWayland.cpp +--- firefox-81.0.1/widget/gtk/WindowSurfaceWayland.cpp.1656727 2020-10-05 16:05:18.057494700 +0200 ++++ firefox-81.0.1/widget/gtk/WindowSurfaceWayland.cpp 2020-10-05 16:06:49.011909031 +0200 +@@ -158,7 +158,6 @@ We allocate shared memory (shm) by mmap( + between us and wayland compositor. We draw our graphics data to the shm and + handle to wayland compositor by WindowBackBuffer/WindowSurfaceWayland + (wl_buffer/wl_surface). +- + */ + + #define EVENT_LOOP_DELAY (1000 / 240) +@@ -166,6 +165,36 @@ handle to wayland compositor by WindowBa + #define BUFFER_BPP 4 + gfx::SurfaceFormat WindowBackBuffer::mFormat = gfx::SurfaceFormat::B8G8R8A8; + ++static mozilla::Mutex* gDelayedCommitLock = nullptr; ++static GList* gDelayedCommits = nullptr; ++ ++static void DelayedCommitsEnsureMutext() { ++ if (!gDelayedCommitLock) { ++ gDelayedCommitLock = new mozilla::Mutex("DelayedCommit lock"); ++ } ++} ++ ++static void DelayedCommitsRemoveSurface(WindowSurfaceWayland* aSurface) { ++ GList* foundCommit = g_list_find(gDelayedCommits, aSurface); ++ if (foundCommit) { ++ MutexAutoLock lock(*gDelayedCommitLock); ++ gDelayedCommits = g_list_delete_link(gDelayedCommits, foundCommit); ++ } ++} ++ ++// When a new window is created we may not have a valid wl_surface ++// for drawing (Gtk haven't created it yet). All commits are queued ++// and CommitWaylandBuffer() is called by timer when wl_surface is ready ++// for drawing. ++static void WaylandBufferDelayCommitHandler(WindowSurfaceWayland* aSurface) { ++ GList* foundCommit = g_list_find(gDelayedCommits, aSurface); ++ if (foundCommit) { ++ aSurface->CommitWaylandBuffer(); ++ MutexAutoLock lock(*gDelayedCommitLock); ++ gDelayedCommits = g_list_delete_link(gDelayedCommits, foundCommit); ++ } ++} ++ + nsWaylandDisplay* WindowBackBuffer::GetWaylandDisplay() { + return mWindowSurfaceWayland->GetWaylandDisplay(); + } +@@ -398,7 +427,6 @@ WindowSurfaceWayland::WindowSurfaceWayla + mWaylandFullscreenDamage(false), + mFrameCallback(nullptr), + mLastCommittedSurface(nullptr), +- mDelayedCommitHandle(nullptr), + mLastCommitTime(0), + mDrawToWaylandBufferDirectly(true), + mCanSwitchWaylandBuffer(true), +@@ -410,6 +438,7 @@ WindowSurfaceWayland::WindowSurfaceWayla + for (int i = 0; i < BACK_BUFFER_NUM; i++) { + mShmBackupBuffer[i] = nullptr; + } ++ DelayedCommitsEnsureMutext(); + } + + WindowSurfaceWayland::~WindowSurfaceWayland() { +@@ -417,12 +446,9 @@ WindowSurfaceWayland::~WindowSurfaceWayl + NS_WARNING("Deleted WindowSurfaceWayland with a pending commit!"); + } + +- if (mDelayedCommitHandle) { +- // Delete reference to this to prevent WaylandBufferDelayCommitHandler() +- // operate on released this. mDelayedCommitHandle itself will +- // be released at WaylandBufferDelayCommitHandler(). +- *mDelayedCommitHandle = nullptr; +- } ++ // Delete reference to this to prevent WaylandBufferDelayCommitHandler() ++ // operate on released this. ++ DelayedCommitsRemoveSurface(this); + + if (mFrameCallback) { + wl_callback_destroy(mFrameCallback); +@@ -863,23 +889,11 @@ bool WindowSurfaceWayland::CommitImageCa + return true; + } + +-static void WaylandBufferDelayCommitHandler(WindowSurfaceWayland** aSurface) { +- if (*aSurface) { +- (*aSurface)->DelayedCommitHandler(); +- } else { +- // Referenced WindowSurfaceWayland is already deleted. +- // Do nothing but just release the mDelayedCommitHandle allocated at +- // WindowSurfaceWayland::CommitWaylandBuffer(). +- free(aSurface); +- } +-} +- + void WindowSurfaceWayland::CommitWaylandBuffer() { + LOGWAYLAND(("WindowSurfaceWayland::CommitWaylandBuffer [%p]\n", (void*)this)); + LOGWAYLAND( + (" mDrawToWaylandBufferDirectly = %d\n", mDrawToWaylandBufferDirectly)); + LOGWAYLAND((" mCanSwitchWaylandBuffer = %d\n", mCanSwitchWaylandBuffer)); +- LOGWAYLAND((" mDelayedCommitHandle = %p\n", mDelayedCommitHandle)); + LOGWAYLAND((" mFrameCallback = %p\n", mFrameCallback)); + LOGWAYLAND((" mLastCommittedSurface = %p\n", mLastCommittedSurface)); + LOGWAYLAND((" mBufferPendingCommit = %d\n", mBufferPendingCommit)); +@@ -915,16 +929,13 @@ void WindowSurfaceWayland::CommitWayland + MOZ_ASSERT(!mFrameCallback || waylandSurface != mLastCommittedSurface, + "Missing wayland surface at frame callback!"); + +- // Do nothing if there's already mDelayedCommitHandle pending. +- if (!mDelayedCommitHandle) { +- mDelayedCommitHandle = static_cast( +- moz_xmalloc(sizeof(*mDelayedCommitHandle))); +- *mDelayedCommitHandle = this; +- ++ GList* foundCommit = g_list_find(gDelayedCommits, this); ++ if (!foundCommit) { ++ MutexAutoLock lock(*gDelayedCommitLock); ++ gDelayedCommits = g_list_prepend(gDelayedCommits, this); + MessageLoop::current()->PostDelayedTask( + NewRunnableFunction("WaylandBackBufferCommit", +- &WaylandBufferDelayCommitHandler, +- mDelayedCommitHandle), ++ &WaylandBufferDelayCommitHandler, this), + EVENT_LOOP_DELAY); + } + return; +@@ -1036,25 +1047,6 @@ void WindowSurfaceWayland::FrameCallback + + CommitWaylandBuffer(); + } +- +-void WindowSurfaceWayland::DelayedCommitHandler() { +- MOZ_ASSERT(mIsMainThread == NS_IsMainThread()); +- MOZ_ASSERT(mDelayedCommitHandle != nullptr, "Missing mDelayedCommitHandle!"); +- +- LOGWAYLAND( +- ("WindowSurfaceWayland::DelayedCommitHandler [%p]\n", (void*)this)); +- +- if (!mDelayedCommitHandle) { +- LOGWAYLAND((" We're missing mDelayedCommitHandle!\n")); +- return; +- } +- +- *mDelayedCommitHandle = nullptr; +- free(mDelayedCommitHandle); +- mDelayedCommitHandle = nullptr; +- +- CommitWaylandBuffer(); +-} + + } // namespace widget + } // namespace mozilla +diff -up firefox-81.0.1/widget/gtk/WindowSurfaceWayland.h.1656727 firefox-81.0.1/widget/gtk/WindowSurfaceWayland.h +--- firefox-81.0.1/widget/gtk/WindowSurfaceWayland.h.1656727 2020-09-30 19:42:37.000000000 +0200 ++++ firefox-81.0.1/widget/gtk/WindowSurfaceWayland.h 2020-10-05 16:05:18.058494705 +0200 +@@ -161,7 +161,7 @@ class WindowSurfaceWayland : public Wind + // If we fail (wayland compositor is busy, + // wl_surface is not created yet) we queue the painting + // and we send it to wayland compositor in FrameCallbackHandler()/ +- // DelayedCommitHandler/CommitWaylandBuffer(). ++ // CommitWaylandBuffer(). + already_AddRefed Lock( + const LayoutDeviceIntRegion& aRegion) override; + void Commit(const LayoutDeviceIntRegion& aInvalidRegion) final; +@@ -171,12 +171,6 @@ class WindowSurfaceWayland : public Wind + // queued commits. + void FrameCallbackHandler(); + +- // When a new window is created we may not have a valid wl_surface +- // for drawing (Gtk haven't created it yet). All commits are queued +- // and DelayedCommitHandler() is called by timer when wl_surface is ready +- // for drawing. +- void DelayedCommitHandler(); +- + // Try to commit all queued drawings to Wayland compositor. This is usually + // called from other routines but can be used to explicitly flush + // all drawings as we do when wl_buffer is released +@@ -249,17 +243,14 @@ class WindowSurfaceWayland : public Wind + wl_callback* mFrameCallback; + wl_surface* mLastCommittedSurface; + +- // Registered reference to pending DelayedCommitHandler() call. +- WindowSurfaceWayland** mDelayedCommitHandle; +- + // Cached drawings. If we can't get WaylandBuffer (wl_buffer) at + // WindowSurfaceWayland::Lock() we direct gecko rendering to + // mImageSurface. + // If we can't get WaylandBuffer at WindowSurfaceWayland::Commit() + // time, mImageSurface is moved to mDelayedImageCommits which + // holds all cached drawings. +- // mDelayedImageCommits can be drawn by FrameCallbackHandler(), +- // DelayedCommitHandler() or when WaylandBuffer is detached. ++ // mDelayedImageCommits can be drawn by FrameCallbackHandler() ++ // or when WaylandBuffer is detached. + RefPtr mImageSurface; + AutoTArray mDelayedImageCommits; + +@@ -282,8 +273,8 @@ class WindowSurfaceWayland : public Wind + // We can't send WaylandBuffer (wl_buffer) to compositor when gecko + // is rendering into it (i.e. between WindowSurfaceWayland::Lock() / + // WindowSurfaceWayland::Commit()). +- // Thus we use mBufferCommitAllowed to disable commit by callbacks +- // (FrameCallbackHandler(), DelayedCommitHandler()) ++ // Thus we use mBufferCommitAllowed to disable commit by ++ // CommitWaylandBuffer(). + bool mBufferCommitAllowed; + + // We need to clear WaylandBuffer when entire transparent window is repainted. diff --git a/pgo.patch b/pgo.patch index 707e7ee..207b3d8 100644 --- a/pgo.patch +++ b/pgo.patch @@ -136,3 +136,4 @@ diff -up firefox-81.0.1/python/mozbuild/mozbuild/build_commands.py.pgo firefox-8 pgo_env['JARLOG_FILE'] = mozpath.join(orig_topobjdir, 'jarlog/en-US.log') pgo_cmd = [ instr.virtualenv_manager.python_path, +