diff options
-rw-r--r-- | firefox.spec | 11 | ||||
-rw-r--r-- | mozilla-1468911.patch | 300 |
2 files changed, 308 insertions, 3 deletions
diff --git a/firefox.spec b/firefox.spec index 6ff7864..74bc291 100644 --- a/firefox.spec +++ b/firefox.spec @@ -1,10 +1,10 @@ # Set to true if it's going to be submitted as update. -%global release_build 1 +%global release_build 0 # Disabled arm due to rhbz#1658940 ExcludeArch: armv7hl # Disabled due to https://pagure.io/fedora-infrastructure/issue/7581 -# ExcludeArch: s390x +ExcludeArch: s390x %global system_nss 1 %global system_ffi 1 @@ -95,7 +95,7 @@ ExcludeArch: armv7hl Summary: Mozilla Firefox Web browser Name: firefox Version: 66.0 -Release: 4%{?pre_tag}%{?dist} +Release: 5%{?pre_tag}%{?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 @@ -156,6 +156,7 @@ Patch575: mozilla-1423598-popup.patch Patch576: mozilla-1532643-popup.patch Patch577: mozilla-1535567.patch Patch578: mozilla-1431399.patch +Patch579: mozilla-1468911.patch # PGO/LTO patches Patch600: pgo.patch @@ -363,6 +364,7 @@ This package contains results of tests executed during build. %patch576 -p1 -b .mozilla-1532643-popup %patch577 -p1 -b .mozilla-1535567 %patch578 -p1 -b .mozilla-1431399 +%patch579 -p1 -b .mozilla-1468911 # PGO patches %patch600 -p1 -b .pgo @@ -910,6 +912,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : #--------------------------------------------------------------------- %changelog +* Mon Mar 18 2019 Martin Stransky <stransky@redhat.com> - 66.0-5 +- Added fix for mozbz#1468911 + * Mon Mar 18 2019 Martin Stransky <stransky@redhat.com> - 66.0-4 - Release build diff --git a/mozilla-1468911.patch b/mozilla-1468911.patch new file mode 100644 index 0000000..d3177ac --- /dev/null +++ b/mozilla-1468911.patch @@ -0,0 +1,300 @@ +changeset: 465236:be9a6c98a4a7 +tag: tip +user: Martin Stransky <stransky@redhat.com> +date: Mon Mar 18 10:42:48 2019 +0100 +summary: tearing + +diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp +--- a/widget/gtk/WindowSurfaceWayland.cpp ++++ b/widget/gtk/WindowSurfaceWayland.cpp +@@ -15,16 +15,32 @@ + #include "nsTArray.h" + #include "base/message_loop.h" // for MessageLoop + #include "base/task.h" // for NewRunnableMethod, etc + + #include <sys/mman.h> + #include <fcntl.h> + #include <errno.h> + ++#undef LOG ++#ifdef MOZ_LOGGING ++ ++# include "mozilla/Logging.h" ++# include "nsTArray.h" ++# include "Units.h" ++ ++extern mozilla::LazyLogModule gWidgetWaylandLog; ++# define LOGWAYLAND(args) MOZ_LOG(gWidgetWaylandLog, mozilla::LogLevel::Debug, args) ++ ++#else ++ ++# define LOGWAYLAND(args) ++ ++#endif /* MOZ_LOGGING */ ++ + namespace mozilla { + namespace widget { + + /* + Wayland multi-thread rendering scheme + + Every rendering thread (main thread, compositor thread) contains its own + nsWaylandDisplay object connected to Wayland compositor (Mutter, Weston, etc.) +@@ -283,23 +299,30 @@ WindowBackBuffer::WindowBackBuffer(nsWay + Create(aWidth, aHeight); + } + + WindowBackBuffer::~WindowBackBuffer() { Release(); } + + bool WindowBackBuffer::Resize(int aWidth, int aHeight) { + if (aWidth == mWidth && aHeight == mHeight) return true; + ++ LOGWAYLAND(("WindowBackBuffer::Resize [%p] %d %d\n", ++ (void*)this, aWidth, aHeight)); ++ + Release(); + Create(aWidth, aHeight); ++ Clear(); + + return (mWaylandBuffer != nullptr); + } + + void WindowBackBuffer::Attach(wl_surface* aSurface) { ++ LOGWAYLAND(("WindowBackBuffer::Attach [%p] wl_surface %p\n", ++ (void*)this, (void *)aSurface)); ++ + wl_surface_attach(aSurface, mWaylandBuffer, 0, 0); + wl_surface_commit(aSurface); + wl_display_flush(mWaylandDisplay->GetDisplay()); + mAttached = true; + } + + void WindowBackBuffer::Detach() { mAttached = false; } + +@@ -340,17 +363,18 @@ WindowSurfaceWayland::WindowSurfaceWayla + mFrameCallback(nullptr), + mLastCommittedSurface(nullptr), + mDisplayThreadMessageLoop(MessageLoop::current()), + mDelayedCommitHandle(nullptr), + mDrawToWaylandBufferDirectly(true), + mPendingCommit(false), + mWaylandBufferFullScreenDamage(false), + mIsMainThread(NS_IsMainThread()), +- mNeedScaleFactorUpdate(true) { ++ mNeedScaleFactorUpdate(true), ++ mNeedFullScreenUpdate(true) { + for (int i = 0; i < BACK_BUFFER_NUM; i++) mBackupBuffer[i] = nullptr; + } + + WindowSurfaceWayland::~WindowSurfaceWayland() { + if (mPendingCommit) { + NS_WARNING("Deleted WindowSurfaceWayland with a pending commit!"); + } + +@@ -392,16 +416,17 @@ WindowBackBuffer* WindowSurfaceWayland:: + } + + if (!mWaylandBuffer->IsAttached()) { + if (!mWaylandBuffer->IsMatchingSize(aWidth, aHeight)) { + mWaylandBuffer->Resize(aWidth, aHeight); + // There's a chance that scale factor has been changed + // when buffer size changed + mNeedScaleFactorUpdate = true; ++ mNeedFullScreenUpdate = true; + } + return mWaylandBuffer; + } + + MOZ_ASSERT(!mPendingCommit, + "Uncommitted buffer switch, screen artifacts ahead."); + + // Front buffer is used by compositor, select a back buffer +@@ -490,39 +515,36 @@ already_AddRefed<gfx::DrawTarget> Window + + B) Lock() is requested for part(s) of screen. We need to provide temporary + surface to draw into and copy result (clipped) to target wl_surface. + */ + already_AddRefed<gfx::DrawTarget> WindowSurfaceWayland::Lock( + const LayoutDeviceIntRegion& aRegion) { + MOZ_ASSERT(mIsMainThread == NS_IsMainThread()); + +- LayoutDeviceIntRect screenRect = mWindow->GetBounds(); +- gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect(); +- gfx::IntSize lockSize(bounds.XMost(), bounds.YMost()); ++ LOGWAYLAND(("WindowSurfaceWayland::Lock [%p]\n", (void*)this)); + + // Are we asked for entire nsWindow to draw? +- mDrawToWaylandBufferDirectly = +- (aRegion.GetNumRects() == 1 && bounds.x == 0 && bounds.y == 0 && +- lockSize.width == screenRect.width && +- lockSize.height == screenRect.height); +- ++ mDrawToWaylandBufferDirectly = IsFullScreenDraw(aRegion); + if (mDrawToWaylandBufferDirectly) { ++ LayoutDeviceIntRect screenRect = mWindow->GetBounds(); + RefPtr<gfx::DrawTarget> dt = + LockWaylandBuffer(screenRect.width, screenRect.height, + mWindow->WaylandSurfaceNeedsClear()); + if (dt) { + return dt.forget(); + } + + // We don't have any front buffer available. Try indirect drawing + // to mImageSurface which is mirrored to front buffer at commit. + mDrawToWaylandBufferDirectly = false; + } + ++ gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect(); ++ gfx::IntSize lockSize(bounds.XMost(), bounds.YMost()); + return LockImageSurface(lockSize); + } + + bool WindowSurfaceWayland::CommitImageSurfaceToWaylandBuffer( + const LayoutDeviceIntRegion& aRegion) { + MOZ_ASSERT(!mDrawToWaylandBufferDirectly); + + LayoutDeviceIntRect screenRect = mWindow->GetBounds(); +@@ -611,31 +633,42 @@ void WindowSurfaceWayland::CommitWayland + // If our stored wl_surface does not match the actual one it means the frame + // callback is no longer active and we should release it. + wl_callback_destroy(mFrameCallback); + mFrameCallback = nullptr; + mLastCommittedSurface = nullptr; + } + + if (mWaylandBufferFullScreenDamage) { ++ // We know we can safely redraw whole screen. + LayoutDeviceIntRect rect = mWindow->GetBounds(); + wl_surface_damage(waylandSurface, 0, 0, rect.width, rect.height); + mWaylandBufferFullScreenDamage = false; + } else { + gint scaleFactor = mWindow->GdkScaleFactor(); + for (auto iter = mWaylandBufferDamage.RectIter(); !iter.Done(); + iter.Next()) { + const mozilla::LayoutDeviceIntRect& r = iter.Get(); + // We need to remove the scale factor because the wl_surface_damage + // also multiplies by current scale factor. + wl_surface_damage(waylandSurface, r.x / scaleFactor, r.y / scaleFactor, + r.width / scaleFactor, r.height / scaleFactor); + } ++ ++ // We have to wait untill whole screen is drawn by Gecko, that happens ++ // when window is created or resized. ++ if (mNeedFullScreenUpdate) { ++ if (!IsFullScreenDraw(mWaylandBufferDamage)) { ++ return; ++ } ++ } + } + ++ mNeedFullScreenUpdate = false; ++ + // Clear all back buffer damage as we're committing + // all requested regions. + mWaylandBufferDamage.SetEmpty(); + + mFrameCallback = wl_surface_frame(waylandSurface); + wl_callback_add_listener(mFrameCallback, &frame_listener, this); + + if (mNeedScaleFactorUpdate || mLastCommittedSurface != waylandSurface) { +@@ -648,16 +681,18 @@ void WindowSurfaceWayland::CommitWayland + + // There's no pending commit, all changes are sent to compositor. + mPendingCommit = false; + } + + void WindowSurfaceWayland::Commit(const LayoutDeviceIntRegion& aInvalidRegion) { + MOZ_ASSERT(mIsMainThread == NS_IsMainThread()); + ++ LOGWAYLAND(("WindowSurfaceWayland::Commit [%p]\n", (void*)this)); ++ + // We have new content at mImageSurface - copy data to mWaylandBuffer first. + if (!mDrawToWaylandBufferDirectly) { + CommitImageSurfaceToWaylandBuffer(aInvalidRegion); + } + + // If we're not at fullscreen damage add drawing area from aInvalidRegion + if (!mWaylandBufferFullScreenDamage) { + mWaylandBufferDamage.OrWith(aInvalidRegion); +@@ -690,10 +725,22 @@ void WindowSurfaceWayland::DelayedCommit + free(mDelayedCommitHandle); + mDelayedCommitHandle = nullptr; + + if (mPendingCommit) { + CommitWaylandBuffer(); + } + } + ++bool WindowSurfaceWayland::IsFullScreenDraw( ++ const LayoutDeviceIntRegion& aRegion) { ++ LayoutDeviceIntRect screenRect = mWindow->GetBounds(); ++ gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect(); ++ gfx::IntSize lockSize(bounds.XMost(), bounds.YMost()); ++ ++ // Are we asked to update entire nsWindow? ++ return (bounds.x == 0 && bounds.y == 0 && ++ lockSize.width == screenRect.width && ++ lockSize.height == screenRect.height); ++} ++ + } // namespace widget + } // namespace mozilla +diff --git a/widget/gtk/WindowSurfaceWayland.h b/widget/gtk/WindowSurfaceWayland.h +--- a/widget/gtk/WindowSurfaceWayland.h ++++ b/widget/gtk/WindowSurfaceWayland.h +@@ -94,16 +94,17 @@ class WindowSurfaceWayland : public Wind + + private: + WindowBackBuffer* GetWaylandBufferToDraw(int aWidth, int aHeight); + + already_AddRefed<gfx::DrawTarget> LockWaylandBuffer(int aWidth, int aHeight, + bool aClearBuffer); + already_AddRefed<gfx::DrawTarget> LockImageSurface( + const gfx::IntSize& aLockSize); ++ bool IsFullScreenDraw(const LayoutDeviceIntRegion& aRegion); + bool CommitImageSurfaceToWaylandBuffer(const LayoutDeviceIntRegion& aRegion); + void CommitWaylandBuffer(); + + // TODO: Do we need to hold a reference to nsWindow object? + nsWindow* mWindow; + nsWaylandDisplay* mWaylandDisplay; + WindowBackBuffer* mWaylandBuffer; + LayoutDeviceIntRegion mWaylandBufferDamage; +@@ -113,14 +114,15 @@ class WindowSurfaceWayland : public Wind + wl_surface* mLastCommittedSurface; + MessageLoop* mDisplayThreadMessageLoop; + WindowSurfaceWayland** mDelayedCommitHandle; + bool mDrawToWaylandBufferDirectly; + bool mPendingCommit; + bool mWaylandBufferFullScreenDamage; + bool mIsMainThread; + bool mNeedScaleFactorUpdate; ++ bool mNeedFullScreenUpdate; + }; + + } // namespace widget + } // namespace mozilla + + #endif // _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_WAYLAND_H +diff --git a/widget/gtk/nsAppShell.cpp b/widget/gtk/nsAppShell.cpp +--- a/widget/gtk/nsAppShell.cpp ++++ b/widget/gtk/nsAppShell.cpp +@@ -35,16 +35,17 @@ using mozilla::widget::ScreenHelperGTK; + using mozilla::widget::ScreenManager; + + #define NOTIFY_TOKEN 0xFA + + LazyLogModule gWidgetLog("Widget"); + LazyLogModule gWidgetFocusLog("WidgetFocus"); + LazyLogModule gWidgetDragLog("WidgetDrag"); + LazyLogModule gWidgetDrawLog("WidgetDraw"); ++LazyLogModule gWidgetWaylandLog("WidgetWayland"); + + static GPollFunc sPollFunc; + + // Wrapper function to disable hang monitoring while waiting in poll(). + static gint PollWrapper(GPollFD* ufds, guint nfsd, gint timeout_) { + mozilla::BackgroundHangMonitor().NotifyWait(); + gint result; + { + |