diff --git a/firefox.spec b/firefox.spec index 1719e43..88f5fc6 100644 --- a/firefox.spec +++ b/firefox.spec @@ -94,7 +94,7 @@ ExcludeArch: ppc64le Summary: Mozilla Firefox Web browser Name: firefox Version: 69.0 -Release: 5%{?pre_tag}%{?dist} +Release: 6%{?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 @@ -166,6 +166,8 @@ Patch582: mozilla-1576268.patch Patch583: mozilla-1579794-1.patch Patch584: mozilla-1579794-2.patch Patch585: mozilla-1579849.patch +Patch586: mozilla-1579823.patch +Patch587: mozilla-1580152.patch # PGO/LTO patches Patch600: pgo.patch @@ -384,6 +386,8 @@ This package contains results of tests executed during build. %patch584 -p1 -b .mozilla-1579794-2 %patch585 -p1 -b .mozilla-1579849 %patch422 -p1 -b .1580174-webrtc-popup +%patch586 -p1 -b .mozilla-1579823 +%patch587 -p1 -b .mozilla-1580152 # PGO patches %patch600 -p1 -b .pgo @@ -960,6 +964,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : #--------------------------------------------------------------------- %changelog +* Mon Sep 16 2019 Martin Stransky - 69.0-6 +- Added fixes for mozbz#1579823, mozbz#1580152 + * Wed Sep 11 2019 Martin Stransky - 69.0-5 - Added fix for mozbz#1579849 - partial screen update when page switches. diff --git a/mozilla-1579823.patch b/mozilla-1579823.patch new file mode 100644 index 0000000..9e00d4f --- /dev/null +++ b/mozilla-1579823.patch @@ -0,0 +1,306 @@ +diff -up firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp.mozilla-1579823 firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp +--- firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp.mozilla-1579823 2019-09-12 07:53:06.119602913 +0200 ++++ firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp 2019-09-12 07:54:47.410105270 +0200 +@@ -326,13 +326,13 @@ void WindowBackBufferShm::Create(int aWi + mHeight = aHeight; + + LOGWAYLAND(( +- "%s [%p] wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, (void*)this, ++ "WindowBackBufferShm::Create [%p] wl_buffer %p ID %d\n", (void*)this, + (void*)mWaylandBuffer, + mWaylandBuffer ? wl_proxy_get_id((struct wl_proxy*)mWaylandBuffer) : -1)); + } + + void WindowBackBufferShm::Release() { +- LOGWAYLAND(("%s [%p]\n", __PRETTY_FUNCTION__, (void*)this)); ++ LOGWAYLAND(("WindowBackBufferShm::Release [%p]\n", (void*)this)); + + wl_buffer_destroy(mWaylandBuffer); + mWidth = mHeight = 0; +@@ -358,8 +358,8 @@ WindowBackBufferShm::~WindowBackBufferSh + bool WindowBackBufferShm::Resize(int aWidth, int aHeight) { + if (aWidth == mWidth && aHeight == mHeight) return true; + +- LOGWAYLAND( +- ("%s [%p] %d %d\n", __PRETTY_FUNCTION__, (void*)this, aWidth, aHeight)); ++ LOGWAYLAND(("WindowBackBufferShm::Resize [%p] %d %d\n", (void*)this, aWidth, ++ aHeight)); + + Release(); + Create(aWidth, aHeight); +@@ -369,7 +369,7 @@ bool WindowBackBufferShm::Resize(int aWi + + void WindowBackBuffer::Attach(wl_surface* aSurface) { + LOGWAYLAND( +- ("%s [%p] wl_surface %p ID %d wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, ++ ("WindowBackBuffer::Attach [%p] wl_surface %p ID %d wl_buffer %p ID %d\n", + (void*)this, (void*)aSurface, + aSurface ? wl_proxy_get_id((struct wl_proxy*)aSurface) : -1, + (void*)GetWlBuffer(), +@@ -382,8 +382,8 @@ void WindowBackBuffer::Attach(wl_surface + } + + void WindowBackBufferShm::Detach(wl_buffer* aBuffer) { +- LOGWAYLAND(("%s [%p] wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, (void*)this, +- (void*)aBuffer, ++ LOGWAYLAND(("WindowBackBufferShm::Detach [%p] wl_buffer %p ID %d\n", ++ (void*)this, (void*)aBuffer, + aBuffer ? wl_proxy_get_id((struct wl_proxy*)aBuffer) : -1)); + + mAttached = false; +@@ -404,7 +404,7 @@ bool WindowBackBufferShm::SetImageDataFr + + already_AddRefed WindowBackBufferShm::Lock() { + LOGWAYLAND(( +- "%s [%p] [%d x %d] wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, ++ "WindowBackBufferShm::Lock [%p] [%d x %d] wl_buffer %p ID %d\n", + (void*)this, mWidth, mHeight, (void*)mWaylandBuffer, + mWaylandBuffer ? wl_proxy_get_id((struct wl_proxy*)mWaylandBuffer) : -1)); + +@@ -419,16 +419,17 @@ WindowBackBufferDMABuf::WindowBackBuffer + nsWaylandDisplay* aWaylandDisplay, int aWidth, int aHeight) + : WindowBackBuffer(aWaylandDisplay) { + mDMAbufSurface.Create(aWidth, aHeight); +- +- LOGWAYLAND(("%s [%p] Created DMABuf buffer [%d x %d]\n", __PRETTY_FUNCTION__, +- (void*)this, aWidth, aHeight)); ++ LOGWAYLAND( ++ ("WindowBackBufferDMABuf::WindowBackBufferDMABuf [%p] Created DMABuf " ++ "buffer [%d x %d]\n", ++ (void*)this, aWidth, aHeight)); + } + + WindowBackBufferDMABuf::~WindowBackBufferDMABuf() { mDMAbufSurface.Release(); } + + already_AddRefed WindowBackBufferDMABuf::Lock() { + LOGWAYLAND( +- ("%s [%p] [%d x %d] wl_buffer %p ID %d\n", __PRETTY_FUNCTION__, ++ ("WindowBackBufferDMABuf::Lock [%p] [%d x %d] wl_buffer %p ID %d\n", + (void*)this, GetWidth(), GetHeight(), (void*)GetWlBuffer(), + GetWlBuffer() ? wl_proxy_get_id((struct wl_proxy*)GetWlBuffer()) : -1)); + +@@ -534,7 +535,8 @@ WindowSurfaceWayland::~WindowSurfaceWayl + bool WindowSurfaceWayland::UseDMABufBackend() { + if (!mUseDMABufInitialized) { + mUseDMABuf = nsWaylandDisplay::IsDMABufEnabled(); +- LOGWAYLAND(("%s DMABuf state %d\n", __PRETTY_FUNCTION__, mUseDMABuf)); ++ LOGWAYLAND(("WindowSurfaceWayland::UseDMABufBackend DMABuf state %d\n", ++ mUseDMABuf)); + mUseDMABufInitialized = true; + } + return mUseDMABuf; +@@ -567,15 +569,16 @@ WindowBackBuffer* WindowSurfaceWayland:: + + WindowBackBuffer* WindowSurfaceWayland::GetWaylandBufferToDraw( + bool aCanSwitchBuffer) { +- LOGWAYLAND(("%s [%p] Requested buffer [%d x %d]\n", __PRETTY_FUNCTION__, +- (void*)this, mBufferScreenRect.width, mBufferScreenRect.height)); ++ LOGWAYLAND( ++ ("WindowSurfaceWayland::GetWaylandBufferToDraw [%p] Requested buffer [%d " ++ "x %d]\n", ++ (void*)this, mBufferScreenRect.width, mBufferScreenRect.height)); + + // There's no buffer created yet, create a new one. + if (!mWaylandBuffer) { + MOZ_ASSERT(aCanSwitchBuffer && mWholeWindowBufferDamage, + "Created new buffer for partial drawing!"); +- LOGWAYLAND(("%s [%p] Created new buffer [%d x %d]\n", __PRETTY_FUNCTION__, +- (void*)this, mBufferScreenRect.width, ++ LOGWAYLAND((" Created new buffer [%d x %d]\n", mBufferScreenRect.width, + mBufferScreenRect.height)); + + mWaylandBuffer = +@@ -586,21 +589,19 @@ WindowBackBuffer* WindowSurfaceWayland:: + + #ifdef DEBUG + if (mWaylandBuffer->IsAttached()) { +- LOGWAYLAND(("%s [%p] Buffer %p is attached, need to find a new one.\n", +- __PRETTY_FUNCTION__, (void*)this, mWaylandBuffer)); ++ LOGWAYLAND((" Buffer %p is attached, need to find a new one.\n", ++ mWaylandBuffer)); + } + #endif + + // Reuse existing buffer + if (!mWaylandBuffer->IsAttached()) { +- LOGWAYLAND( +- ("%s [%p] Use recent buffer.\n", __PRETTY_FUNCTION__, (void*)this)); ++ LOGWAYLAND((" Use recent buffer.\n")); + + if (mWaylandBuffer->IsMatchingSize(mBufferScreenRect.width, + mBufferScreenRect.height)) { +- LOGWAYLAND(("%s [%p] Size is ok, use the buffer [%d x %d]\n", +- __PRETTY_FUNCTION__, (void*)this, mBufferScreenRect.width, +- mBufferScreenRect.height)); ++ LOGWAYLAND((" Size is ok, use the buffer [%d x %d]\n", ++ mBufferScreenRect.width, mBufferScreenRect.height)); + return mWaylandBuffer; + } + +@@ -609,9 +610,8 @@ WindowBackBuffer* WindowSurfaceWayland:: + return nullptr; + } + +- LOGWAYLAND(("%s [%p] Reuse buffer with resize [%d x %d]\n", +- __PRETTY_FUNCTION__, (void*)this, mBufferScreenRect.width, +- mBufferScreenRect.height)); ++ LOGWAYLAND((" Reuse buffer with resize [%d x %d]\n", ++ mBufferScreenRect.width, mBufferScreenRect.height)); + + mWaylandBuffer->Resize(mBufferScreenRect.width, mBufferScreenRect.height); + // There's a chance that scale factor has been changed +@@ -629,8 +629,7 @@ WindowBackBuffer* WindowSurfaceWayland:: + for (availableBuffer = 0; availableBuffer < BACK_BUFFER_NUM; + availableBuffer++) { + if (!mBackupBuffer[availableBuffer]) { +- LOGWAYLAND(("%s [%p] Created new buffer [%d x %d]\n", __PRETTY_FUNCTION__, +- (void*)this, mBufferScreenRect.width, ++ LOGWAYLAND((" Created new buffer [%d x %d]\n", mBufferScreenRect.width, + mBufferScreenRect.height)); + mBackupBuffer[availableBuffer] = CreateWaylandBuffer( + mBufferScreenRect.width, mBufferScreenRect.height); +@@ -643,8 +642,7 @@ WindowBackBuffer* WindowSurfaceWayland:: + } + + if (MOZ_UNLIKELY(availableBuffer == BACK_BUFFER_NUM)) { +- LOGWAYLAND(("%s [%p] No drawing buffer available!\n", __PRETTY_FUNCTION__, +- (void*)this)); ++ LOGWAYLAND((" No drawing buffer available!\n")); + NS_WARNING("No drawing buffer available"); + return nullptr; + } +@@ -653,17 +651,15 @@ WindowBackBuffer* WindowSurfaceWayland:: + mWaylandBuffer = mBackupBuffer[availableBuffer]; + mBackupBuffer[availableBuffer] = lastWaylandBuffer; + +- LOGWAYLAND(("%s [%p] Buffer flip new back %p new front %p \n", +- __PRETTY_FUNCTION__, (void*)this, (void*)lastWaylandBuffer, +- (void*)mWaylandBuffer)); ++ LOGWAYLAND((" Buffer flip new back %p new front %p \n", ++ (void*)lastWaylandBuffer, (void*)mWaylandBuffer)); + + mNeedScaleFactorUpdate = true; + + bool bufferNeedsResize = !mWaylandBuffer->IsMatchingSize( + mBufferScreenRect.width, mBufferScreenRect.height); + if (bufferNeedsResize) { +- LOGWAYLAND(("%s [%p] Resize buffer to [%d x %d]\n", __PRETTY_FUNCTION__, +- (void*)this, mBufferScreenRect.width, ++ LOGWAYLAND((" Resize buffer to [%d x %d]\n", mBufferScreenRect.width, + mBufferScreenRect.height)); + mWaylandBuffer->Resize(mBufferScreenRect.width, mBufferScreenRect.height); + } +@@ -675,8 +671,8 @@ already_AddRefed Window + bool aCanSwitchBuffer) { + WindowBackBuffer* buffer = GetWaylandBufferToDraw(aCanSwitchBuffer); + +- LOGWAYLAND(("%s [%p] Got buffer %p\n", __PRETTY_FUNCTION__, (void*)this, +- (void*)buffer)); ++ LOGWAYLAND(("WindowSurfaceWayland::LockWaylandBuffer [%p] Got buffer %p\n", ++ (void*)this, (void*)buffer)); + + if (!buffer) { + return nullptr; +@@ -691,7 +687,7 @@ already_AddRefed Window + } + + void WindowSurfaceWayland::UnlockWaylandBuffer() { +- LOGWAYLAND(("%s [%p]\n", __PRETTY_FUNCTION__, (void*)this)); ++ LOGWAYLAND(("WindowSurfaceWayland::UnlockWaylandBuffer [%p]\n", (void*)this)); + mWaylandBuffer->Unlock(); + } + +@@ -774,9 +770,11 @@ already_AddRefed Window + mWindow->WaylandSurfaceNeedsClear() || isTransparentPopup; + } + +- LOGWAYLAND(("%s [%p] lockSize [%d x %d] windowSize [%d x %d]\n", +- __PRETTY_FUNCTION__, (void*)this, lockSize.width, lockSize.height, +- lockedScreenRect.width, lockedScreenRect.height)); ++ LOGWAYLAND( ++ ("WindowSurfaceWayland::Lock [%p] lockSize [%d x %d] windowSize [%d x " ++ "%d]\n", ++ (void*)this, lockSize.width, lockSize.height, lockedScreenRect.width, ++ lockedScreenRect.height)); + LOGWAYLAND((" nsWindow = %p\n", mWindow)); + LOGWAYLAND((" isPopup = %d\n", mWindow->IsWaylandPopup())); + LOGWAYLAND((" isTransparentPopup = %d\n", isTransparentPopup)); +@@ -892,8 +890,10 @@ bool WindowSurfaceWayland::CommitImageSu + MOZ_ASSERT(!rect.IsEmpty(), "Empty drawing?"); + #endif + +- LOGWAYLAND(("%s [%p] screenSize [%d x %d]\n", __PRETTY_FUNCTION__, +- (void*)this, mBufferScreenRect.width, mBufferScreenRect.height)); ++ LOGWAYLAND( ++ ("WindowSurfaceWayland::CommitImageSurfaceToWaylandBuffer [%p] " ++ "screenSize [%d x %d]\n", ++ (void*)this, mBufferScreenRect.width, mBufferScreenRect.height)); + + mDelayedImageCommits.AppendElement( + WindowImageSurface(mImageSurface, aRegion)); +@@ -930,7 +930,7 @@ static void WaylandBufferDelayCommitHand + void WindowSurfaceWayland::CommitWaylandBuffer() { + MOZ_ASSERT(mPendingCommit, "Committing empty surface!"); + +- LOGWAYLAND(("%s [%p]\n", __PRETTY_FUNCTION__, (void*)this)); ++ LOGWAYLAND(("WindowSurfaceWayland::CommitWaylandBuffer [%p]\n", (void*)this)); + LOGWAYLAND( + (" mDrawToWaylandBufferDirectly = %d\n", mDrawToWaylandBufferDirectly)); + LOGWAYLAND((" mWholeWindowBufferDamage = %d\n", mWholeWindowBufferDamage)); +@@ -940,8 +940,8 @@ void WindowSurfaceWayland::CommitWayland + + wl_surface* waylandSurface = mWindow->GetWaylandSurface(); + if (!waylandSurface) { +- LOGWAYLAND(("%s [%p] mWindow->GetWaylandSurface() failed, delay commit.\n", +- __PRETTY_FUNCTION__, (void*)this)); ++ LOGWAYLAND((" [%p] mWindow->GetWaylandSurface() failed, delay commit.\n", ++ (void*)this)); + + // Target window is not created yet - delay the commit. This can happen only + // when the window is newly created and there's no active +@@ -969,8 +969,7 @@ void WindowSurfaceWayland::CommitWayland + // We have an active frame callback request so handle it. + if (mFrameCallback) { + if (waylandSurface == mLastCommittedSurface) { +- LOGWAYLAND(("%s [%p] wait for frame callback.\n", __PRETTY_FUNCTION__, +- (void*)this)); ++ LOGWAYLAND((" [%p] wait for frame callback.\n", (void*)this)); + // We have an active frame callback pending from our recent surface. + // It means we should defer the commit to FrameCallbackHandler(). + return; +@@ -1022,10 +1021,11 @@ void WindowSurfaceWayland::Commit(const + gfx::IntRect bounds = aInvalidRegion.GetBounds().ToUnknownRect(); + gfx::IntSize lockSize(bounds.XMost(), bounds.YMost()); + +- LOGWAYLAND(("%s [%p] lockSize [%d x %d] screenSize [%d x %d]\n", +- __PRETTY_FUNCTION__, (void*)this, lockSize.width, +- lockSize.height, mBufferScreenRect.width, +- mBufferScreenRect.height)); ++ LOGWAYLAND( ++ ("WindowSurfaceWayland::Commit [%p] lockSize [%d x %d] screenSize [%d " ++ "x %d]\n", ++ (void*)this, lockSize.width, lockSize.height, mBufferScreenRect.width, ++ mBufferScreenRect.height)); + LOGWAYLAND((" mDrawToWaylandBufferDirectly = %d\n", + mDrawToWaylandBufferDirectly)); + LOGWAYLAND( +@@ -1064,7 +1064,8 @@ void WindowSurfaceWayland::FrameCallback + MOZ_ASSERT(mLastCommittedSurface != nullptr, + "FrameCallbackHandler() called without valid wl_surface!"); + +- LOGWAYLAND(("%s [%p]\n", __PRETTY_FUNCTION__, (void*)this)); ++ LOGWAYLAND( ++ ("WindowSurfaceWayland::FrameCallbackHandler [%p]\n", (void*)this)); + + wl_callback_destroy(mFrameCallback); + mFrameCallback = nullptr; +@@ -1077,7 +1078,8 @@ void WindowSurfaceWayland::FrameCallback + void WindowSurfaceWayland::DelayedCommitHandler() { + MOZ_ASSERT(mDelayedCommitHandle != nullptr, "Missing mDelayedCommitHandle!"); + +- LOGWAYLAND(("%s [%p]\n", __PRETTY_FUNCTION__, (void*)this)); ++ LOGWAYLAND( ++ ("WindowSurfaceWayland::DelayedCommitHandler [%p]\n", (void*)this)); + + *mDelayedCommitHandle = nullptr; + free(mDelayedCommitHandle); diff --git a/mozilla-1580152.patch b/mozilla-1580152.patch new file mode 100644 index 0000000..43a5264 --- /dev/null +++ b/mozilla-1580152.patch @@ -0,0 +1,617 @@ +diff -up firefox-69.0/widget/gtk/mozwayland/mozwayland.h.mozilla-1580152 firefox-69.0/widget/gtk/mozwayland/mozwayland.h +--- firefox-69.0/widget/gtk/mozwayland/mozwayland.h.mozilla-1580152 2019-09-16 10:43:50.214742949 +0200 ++++ firefox-69.0/widget/gtk/mozwayland/mozwayland.h 2019-09-16 10:43:50.222742921 +0200 +@@ -27,6 +27,9 @@ MOZ_EXPORT struct wl_proxy* wl_proxy_mar + struct wl_proxy* proxy, uint32_t opcode, + const struct wl_interface* interface, ...); + ++MOZ_EXPORT void* wl_proxy_create_wrapper(void* proxy); ++MOZ_EXPORT void wl_proxy_wrapper_destroy(void* proxy_wrapper); ++ + /* We need implement some missing functions from wayland-client-protocol.h + */ + #ifndef WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM +diff -up firefox-69.0/widget/gtk/nsWaylandDisplay.cpp.mozilla-1580152 firefox-69.0/widget/gtk/nsWaylandDisplay.cpp +--- firefox-69.0/widget/gtk/nsWaylandDisplay.cpp.mozilla-1580152 2019-09-16 10:43:50.215742946 +0200 ++++ firefox-69.0/widget/gtk/nsWaylandDisplay.cpp 2019-09-16 10:50:58.647224684 +0200 +@@ -243,6 +243,61 @@ bool nsWaylandDisplay::DispatchEventQueu + return true; + } + ++void nsWaylandDisplay::SyncEnd() { ++ wl_callback_destroy(mSyncCallback); ++ mSyncCallback = NULL; ++} ++ ++static void wayland_sync_callback(void* data, struct wl_callback* callback, ++ uint32_t time) { ++ auto display = static_cast(data); ++ display->SyncEnd(); ++} ++ ++static const struct wl_callback_listener sync_callback_listener = { ++ .done = wayland_sync_callback}; ++ ++void nsWaylandDisplay::SyncBegin() { ++ WaitForSyncEnd(); ++ ++ // Use wl_display_sync() to synchronize wayland events. ++ // See dri2_wl_swap_buffers_with_damage() from MESA ++ // or wl_display_roundtrip_queue() from wayland-client. ++ struct wl_display* displayWrapper = ++ static_cast(wl_proxy_create_wrapper((void*)mDisplay)); ++ if (!displayWrapper) { ++ NS_WARNING("Failed to create wl_proxy wrapper!"); ++ return; ++ } ++ ++ wl_proxy_set_queue((struct wl_proxy*)displayWrapper, mEventQueue); ++ mSyncCallback = wl_display_sync(displayWrapper); ++ wl_proxy_wrapper_destroy((void*)displayWrapper); ++ ++ if (!mSyncCallback) { ++ NS_WARNING("Failed to create wl_display_sync callback!"); ++ return; ++ } ++ ++ wl_callback_add_listener(mSyncCallback, &sync_callback_listener, this); ++ wl_display_flush(mDisplay); ++} ++ ++void nsWaylandDisplay::WaitForSyncEnd() { ++ // We're done here ++ if (!mSyncCallback) { ++ return; ++ } ++ ++ while (mSyncCallback != NULL) { ++ if (wl_display_dispatch_queue(mDisplay, mEventQueue) == -1) { ++ NS_WARNING("wl_display_dispatch_queue failed!"); ++ SyncEnd(); ++ return; ++ } ++ } ++} ++ + bool nsWaylandDisplay::Matches(wl_display* aDisplay) { + return mThreadId == PR_GetCurrentThread() && aDisplay == mDisplay; + } +@@ -305,6 +360,7 @@ nsWaylandDisplay::nsWaylandDisplay(wl_di + mSubcompositor(nullptr), + mSeat(nullptr), + mShm(nullptr), ++ mSyncCallback(nullptr), + mPrimarySelectionDeviceManager(nullptr), + mRegistry(nullptr), + mGbmDevice(nullptr), +diff -up firefox-69.0/widget/gtk/nsWaylandDisplay.h.mozilla-1580152 firefox-69.0/widget/gtk/nsWaylandDisplay.h +--- firefox-69.0/widget/gtk/nsWaylandDisplay.h.mozilla-1580152 2019-09-16 10:43:50.215742946 +0200 ++++ firefox-69.0/widget/gtk/nsWaylandDisplay.h 2019-09-16 10:43:50.222742921 +0200 +@@ -41,6 +41,11 @@ class nsWaylandDisplay { + virtual ~nsWaylandDisplay(); + + bool DispatchEventQueue(); ++ ++ void SyncBegin(); ++ void SyncEnd(); ++ void WaitForSyncEnd(); ++ + bool Matches(wl_display* aDisplay); + + MessageLoop* GetDispatcherThreadLoop() { return mDispatcherThreadLoop; } +@@ -90,6 +95,7 @@ class nsWaylandDisplay { + wl_subcompositor* mSubcompositor; + wl_seat* mSeat; + wl_shm* mShm; ++ wl_callback* mSyncCallback; + gtk_primary_selection_device_manager* mPrimarySelectionDeviceManager; + wl_registry* mRegistry; + zwp_linux_dmabuf_v1* mDmabuf; +diff -up firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp.mozilla-1580152 firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp +--- firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp.mozilla-1580152 2019-09-16 10:43:50.220742928 +0200 ++++ firefox-69.0/widget/gtk/WindowSurfaceWayland.cpp 2019-09-16 11:08:00.079998054 +0200 +@@ -32,6 +32,9 @@ extern mozilla::LazyLogModule gWidgetWay + # define LOGWAYLAND(args) + #endif /* MOZ_LOGGING */ + ++// Maximal compositin timeout it miliseconds ++#define COMPOSITING_TIMEOUT 200 ++ + namespace mozilla { + namespace widget { + +@@ -198,6 +201,10 @@ available and gfx.wayland_dmabuf_backend + #define BUFFER_BPP 4 + gfx::SurfaceFormat WindowBackBuffer::mFormat = gfx::SurfaceFormat::B8G8R8A8; + ++nsWaylandDisplay* WindowBackBuffer::GetWaylandDisplay() { ++ return mWindowSurfaceWayland->GetWaylandDisplay(); ++} ++ + int WaylandShmPool::CreateTemporaryFile(int aSize) { + const char* tmppath = getenv("XDG_RUNTIME_DIR"); + MOZ_RELEASE_ASSERT(tmppath, "Missing XDG_RUNTIME_DIR env variable."); +@@ -342,10 +349,11 @@ void WindowBackBufferShm::Clear() { + memset(mShmPool.GetImageData(), 0, mHeight * mWidth * BUFFER_BPP); + } + +-WindowBackBufferShm::WindowBackBufferShm(nsWaylandDisplay* aWaylandDisplay, +- int aWidth, int aHeight) +- : WindowBackBuffer(aWaylandDisplay), +- mShmPool(aWaylandDisplay, aWidth * aHeight * BUFFER_BPP), ++WindowBackBufferShm::WindowBackBufferShm( ++ WindowSurfaceWayland* aWindowSurfaceWayland, int aWidth, int aHeight) ++ : WindowBackBuffer(aWindowSurfaceWayland), ++ mShmPool(aWindowSurfaceWayland->GetWaylandDisplay(), ++ aWidth * aHeight * BUFFER_BPP), + mWaylandBuffer(nullptr), + mWidth(aWidth), + mHeight(aHeight), +@@ -387,6 +395,9 @@ void WindowBackBufferShm::Detach(wl_buff + aBuffer ? wl_proxy_get_id((struct wl_proxy*)aBuffer) : -1)); + + mAttached = false; ++ ++ // Commit any potential cached drawings from latest Lock()/Commit() cycle. ++ mWindowSurfaceWayland->CommitWaylandBuffer(); + } + + bool WindowBackBufferShm::SetImageDataFromBuffer( +@@ -416,8 +427,8 @@ already_AddRefed Window + } + + WindowBackBufferDMABuf::WindowBackBufferDMABuf( +- nsWaylandDisplay* aWaylandDisplay, int aWidth, int aHeight) +- : WindowBackBuffer(aWaylandDisplay) { ++ WindowSurfaceWayland* aWindowSurfaceWayland, int aWidth, int aHeight) ++ : WindowBackBuffer(aWindowSurfaceWayland) { + mDMAbufSurface.Create(aWidth, aHeight); + LOGWAYLAND( + ("WindowBackBufferDMABuf::WindowBackBufferDMABuf [%p] Created DMABuf " +@@ -475,6 +486,9 @@ bool WindowBackBufferDMABuf::SetImageDat + + void WindowBackBufferDMABuf::Detach(wl_buffer* aBuffer) { + mDMAbufSurface.WLBufferDetach(); ++ ++ // Commit any potential cached drawings from latest Lock()/Commit() cycle. ++ mWindowSurfaceWayland->CommitWaylandBuffer(); + } + + void WindowBackBufferDMABuf::Clear() { mDMAbufSurface.Clear(); } +@@ -496,10 +510,11 @@ WindowSurfaceWayland::WindowSurfaceWayla + mWaylandBuffer(nullptr), + mFrameCallback(nullptr), + mLastCommittedSurface(nullptr), +- mDisplayThreadMessageLoop(MessageLoop::current()), + mDelayedCommitHandle(nullptr), ++ mLastCommitTime(0), + mDrawToWaylandBufferDirectly(true), +- mPendingCommit(false), ++ mBufferPendingCommit(false), ++ mBufferCommitAllowed(false), + mWholeWindowBufferDamage(false), + mBufferNeedsClear(false), + mIsMainThread(NS_IsMainThread()), +@@ -508,7 +523,7 @@ WindowSurfaceWayland::WindowSurfaceWayla + } + + WindowSurfaceWayland::~WindowSurfaceWayland() { +- if (mPendingCommit) { ++ if (mBufferPendingCommit) { + NS_WARNING("Deleted WindowSurfaceWayland with a pending commit!"); + } + +@@ -547,7 +562,7 @@ WindowBackBuffer* WindowSurfaceWayland:: + if (UseDMABufBackend()) { + static bool sDMABufBufferCreated = false; + WindowBackBuffer* buffer = +- new WindowBackBufferDMABuf(mWaylandDisplay, aWidth, aHeight); ++ new WindowBackBufferDMABuf(this, aWidth, aHeight); + if (buffer) { + sDMABufBufferCreated = true; + return buffer; +@@ -564,7 +579,7 @@ WindowBackBuffer* WindowSurfaceWayland:: + } + } + +- return new WindowBackBufferShm(mWaylandDisplay, aWidth, aHeight); ++ return new WindowBackBufferShm(this, aWidth, aHeight); + } + + WindowBackBuffer* WindowSurfaceWayland::GetWaylandBufferToDraw( +@@ -675,6 +690,11 @@ already_AddRefed Window + (void*)this, (void*)buffer)); + + if (!buffer) { ++ if (mLastCommitTime && (g_get_monotonic_time() / 1000) - mLastCommitTime > ++ COMPOSITING_TIMEOUT) { ++ NS_WARNING( ++ "Slow response from Wayland compositor, visual glitches ahead."); ++ } + return nullptr; + } + +@@ -724,10 +744,9 @@ static bool IsPopupFullScreenUpdate(Layo + // box is equal to window borders. + if (aRegion.GetNumRects() > 2) return false; + +- gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect(); +- gfx::IntSize lockSize(bounds.XMost(), bounds.YMost()); +- +- return (screenRect.width == lockSize.width && ++ IntRect lockSize = aRegion.GetBounds().ToUnknownRect(); ++ return (lockSize.x == 0 && lockSize.y == 0 && ++ screenRect.width == lockSize.width && + screenRect.height == lockSize.height); + } + +@@ -738,8 +757,7 @@ static bool IsPopupFullScreenUpdate(Layo + to clip/buffer the drawing and we can return wl_buffer directly + for drawing. + - mWaylandBuffer is available - that's an ideal situation. +- - mWaylandBuffer is locked by compositor - flip buffers and draw. +- - if we can't flip buffers - go B) ++ - mWaylandBuffer is locked by compositor - go B) + + 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. +@@ -747,14 +765,17 @@ static bool IsPopupFullScreenUpdate(Layo + already_AddRefed WindowSurfaceWayland::Lock( + const LayoutDeviceIntRegion& aRegion) { + MOZ_ASSERT(mIsMainThread == NS_IsMainThread()); +- +- // Disable all commits from frame callback handler and delayed comit handler +- // as we're updated by gecko compositor. +- mPendingCommit = false; ++ ++ // Wait until all pending events are processed. There may be queued ++ // wl_buffer release event which releases our wl_buffer for further rendering. ++ mWaylandDisplay->WaitForSyncEnd(); ++ ++ // Disable all commits (from potential frame callback/delayed handlers) ++ // until next WindowSurfaceWayland::Commit() call. ++ mBufferCommitAllowed = false; + + LayoutDeviceIntRect lockedScreenRect = mWindow->GetBounds(); +- gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect(); +- gfx::IntSize lockSize(bounds.XMost(), bounds.YMost()); ++ gfx::IntRect lockSize = aRegion.GetBounds().ToUnknownRect(); + + // Are we asked for entire nsWindow to draw? + bool isTransparentPopup = +@@ -775,10 +796,10 @@ already_AddRefed Window + } + + LOGWAYLAND( +- ("WindowSurfaceWayland::Lock [%p] lockSize [%d x %d] windowSize [%d x " +- "%d]\n", +- (void*)this, lockSize.width, lockSize.height, lockedScreenRect.width, +- lockedScreenRect.height)); ++ ("WindowSurfaceWayland::Lock [%p] [%d,%d] -> [%d x %d] rects %d " ++ "windowSize [%d x %d]\n", ++ (void*)this, lockSize.x, lockSize.y, lockSize.width, lockSize.height, ++ aRegion.GetNumRects(), lockedScreenRect.width, lockedScreenRect.height)); + LOGWAYLAND((" nsWindow = %p\n", mWindow)); + LOGWAYLAND((" isPopup = %d\n", mWindow->IsWaylandPopup())); + LOGWAYLAND((" isTransparentPopup = %d\n", isTransparentPopup)); +@@ -789,7 +810,7 @@ already_AddRefed Window + LOGWAYLAND((" mBufferNeedsClear = %d\n", mBufferNeedsClear)); + LOGWAYLAND((" mWholeWindowBufferDamage = %d\n", mWholeWindowBufferDamage)); + +-#if DEBUG ++#if MOZ_LOGGING + if (!(mBufferScreenRect == lockedScreenRect)) { + LOGWAYLAND((" screen size changed\n")); + } +@@ -836,7 +857,7 @@ already_AddRefed Window + mDrawToWaylandBufferDirectly = false; + + LOGWAYLAND((" Indirect drawing.\n")); +- return LockImageSurface(lockSize); ++ return LockImageSurface(gfx::IntSize(lockSize.XMost(), lockSize.YMost())); + } + + void WindowImageSurface::Draw(gfx::SourceSurface* aSurface, +@@ -875,34 +896,42 @@ WindowImageSurface::WindowImageSurface( + mImageSurface->Format()); + } + ++void WindowSurfaceWayland::CacheImageSurface( ++ const LayoutDeviceIntRegion& aRegion) { ++#ifdef MOZ_LOGGING ++ gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect(); ++ LOGWAYLAND(("WindowSurfaceWayland::CacheImageSurface [%p]\n", (void*)this)); ++ LOGWAYLAND((" rects num %d\n", aRegion.GetNumRects())); ++ LOGWAYLAND((" bounds [ %d, %d] -> [%d x %d]\n", bounds.x, bounds.y, ++ bounds.width, bounds.height)); ++#endif ++ ++ mDelayedImageCommits.AppendElement( ++ WindowImageSurface(mImageSurface, aRegion)); ++ // mImageSurface is owned by mDelayedImageCommits ++ mImageSurface = nullptr; ++ ++ LOGWAYLAND( ++ (" There's %d cached images\n", int(mDelayedImageCommits.Length()))); ++} ++ + void WindowSurfaceWayland::DrawDelayedImageCommits( + gfx::DrawTarget* aDrawTarget, LayoutDeviceIntRegion& aWaylandBufferDamage) { ++ LOGWAYLAND( ++ ("WindowSurfaceWayland::DrawDelayedImageCommits [%p]\n", (void*)this)); ++ + for (unsigned int i = 0; i < mDelayedImageCommits.Length(); i++) { + mDelayedImageCommits[i].Draw(aDrawTarget, aWaylandBufferDamage); + } + mDelayedImageCommits.Clear(); + } + +-bool WindowSurfaceWayland::CommitImageSurfaceToWaylandBuffer( +- const LayoutDeviceIntRegion& aRegion, +- LayoutDeviceIntRegion& aWaylandBufferDamage) { ++bool WindowSurfaceWayland::CommitImageCacheToWaylandBuffer() { + MOZ_ASSERT(!mDrawToWaylandBufferDirectly); + +-#ifdef DEBUG +- gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect(); +- gfx::Rect rect(bounds); +- MOZ_ASSERT(!rect.IsEmpty(), "Empty drawing?"); +-#endif +- +- LOGWAYLAND( +- ("WindowSurfaceWayland::CommitImageSurfaceToWaylandBuffer [%p] " +- "screenSize [%d x %d]\n", +- (void*)this, mBufferScreenRect.width, mBufferScreenRect.height)); +- +- mDelayedImageCommits.AppendElement( +- WindowImageSurface(mImageSurface, aRegion)); +- // mImageSurface is owned by mDelayedImageCommits +- mImageSurface = nullptr; ++ if (!mDelayedImageCommits.Length()) { ++ return false; ++ } + + RefPtr dt = LockWaylandBuffer( + /* aCanSwitchBuffer */ mWholeWindowBufferDamage); +@@ -911,10 +940,10 @@ bool WindowSurfaceWayland::CommitImageSu + } + + LOGWAYLAND((" Flushing %ld cached WindowImageSurfaces to Wayland buffer\n", +- long(mDelayedImageCommits.Length() + 1))); ++ long(mDelayedImageCommits.Length()))); + + // Draw any delayed image commits first +- DrawDelayedImageCommits(dt, aWaylandBufferDamage); ++ DrawDelayedImageCommits(dt, mWaylandBufferDamage); + UnlockWaylandBuffer(); + + return true; +@@ -932,7 +961,8 @@ static void WaylandBufferDelayCommitHand + } + + void WindowSurfaceWayland::CommitWaylandBuffer() { +- MOZ_ASSERT(mPendingCommit, "Committing empty surface!"); ++ MOZ_ASSERT(!mWaylandBuffer->IsAttached(), ++ "We can't draw to attached wayland buffer!"); + + LOGWAYLAND(("WindowSurfaceWayland::CommitWaylandBuffer [%p]\n", (void*)this)); + LOGWAYLAND( +@@ -941,6 +971,21 @@ void WindowSurfaceWayland::CommitWayland + LOGWAYLAND((" mDelayedCommitHandle = %p\n", mDelayedCommitHandle)); + LOGWAYLAND((" mFrameCallback = %p\n", mFrameCallback)); + LOGWAYLAND((" mLastCommittedSurface = %p\n", mLastCommittedSurface)); ++ LOGWAYLAND((" mBufferPendingCommit = %d\n", mBufferPendingCommit)); ++ LOGWAYLAND((" mBufferCommitAllowed = %d\n", mBufferCommitAllowed)); ++ ++ if (!mBufferCommitAllowed) { ++ return; ++ } ++ ++ if (CommitImageCacheToWaylandBuffer()) { ++ mBufferPendingCommit = true; ++ } ++ ++ // There's nothing to do here ++ if (!mBufferPendingCommit) { ++ return; ++ } + + wl_surface* waylandSurface = mWindow->GetWaylandSurface(); + if (!waylandSurface) { +@@ -986,6 +1031,7 @@ void WindowSurfaceWayland::CommitWayland + } + + if (mWholeWindowBufferDamage) { ++ LOGWAYLAND((" send whole screen damage\n")); + wl_surface_damage(waylandSurface, 0, 0, mBufferScreenRect.width, + mBufferScreenRect.height); + mWholeWindowBufferDamage = false; +@@ -994,6 +1040,8 @@ void WindowSurfaceWayland::CommitWayland + for (auto iter = mWaylandBufferDamage.RectIter(); !iter.Done(); + iter.Next()) { + mozilla::LayoutDeviceIntRect r = iter.Get(); ++ LOGWAYLAND((" wl_surface_damage_buffer [%d, %d] -> [%d, %d]\n", r.x, ++ r.y, r.width, r.height)); + wl_surface_damage_buffer(waylandSurface, r.x, r.y, r.width, r.height); + } + } +@@ -1012,24 +1060,31 @@ void WindowSurfaceWayland::CommitWayland + + mWaylandBuffer->Attach(waylandSurface); + mLastCommittedSurface = waylandSurface; ++ mLastCommitTime = g_get_monotonic_time() / 1000; ++ ++ // Ask wl_display to start events synchronization. We're going wait ++ // until all events are processed before next WindowSurfaceWayland::Lock() ++ // as we need freed wl_buffer there. ++ mWaylandDisplay->SyncBegin(); + + // There's no pending commit, all changes are sent to compositor. +- mPendingCommit = false; ++ mBufferPendingCommit = false; + } + + void WindowSurfaceWayland::Commit(const LayoutDeviceIntRegion& aInvalidRegion) { + MOZ_ASSERT(mIsMainThread == NS_IsMainThread()); + +-#ifdef DEBUG +- { +- gfx::IntRect bounds = aInvalidRegion.GetBounds().ToUnknownRect(); +- gfx::IntSize lockSize(bounds.XMost(), bounds.YMost()); ++ // Flush all waiting events explicitly as we need ++ // mWaylandDisplay->FlushEventQueue(); + ++#ifdef MOZ_LOGGING ++ { ++ gfx::IntRect lockSize = aInvalidRegion.GetBounds().ToUnknownRect(); + LOGWAYLAND( +- ("WindowSurfaceWayland::Commit [%p] lockSize [%d x %d] screenSize [%d " +- "x %d]\n", +- (void*)this, lockSize.width, lockSize.height, mBufferScreenRect.width, +- mBufferScreenRect.height)); ++ ("WindowSurfaceWayland::Commit [%p] damage size [%d, %d] -> [%d x %d]" ++ "screenSize [%d x %d]\n", ++ (void*)this, lockSize.x, lockSize.y, lockSize.width, lockSize.height, ++ mBufferScreenRect.width, mBufferScreenRect.height)); + LOGWAYLAND((" mDrawToWaylandBufferDirectly = %d\n", + mDrawToWaylandBufferDirectly)); + LOGWAYLAND( +@@ -1044,21 +1099,15 @@ void WindowSurfaceWayland::Commit(const + mWaylandBufferDamage.OrWith(aInvalidRegion); + } + UnlockWaylandBuffer(); +- mPendingCommit = true; ++ mBufferPendingCommit = true; + } else { + MOZ_ASSERT(!mWaylandBuffer->IsLocked(), + "Drawing to already locked buffer?"); +- if (CommitImageSurfaceToWaylandBuffer(aInvalidRegion, +- mWaylandBufferDamage)) { +- // Our cached drawing is flushed, we can draw fullscreen again. +- mDrawToWaylandBufferDirectly = true; +- mPendingCommit = true; +- } ++ CacheImageSurface(aInvalidRegion); + } + +- if (mPendingCommit) { +- CommitWaylandBuffer(); +- } ++ mBufferCommitAllowed = true; ++ CommitWaylandBuffer(); + } + + void WindowSurfaceWayland::FrameCallbackHandler() { +@@ -1074,9 +1123,7 @@ void WindowSurfaceWayland::FrameCallback + wl_callback_destroy(mFrameCallback); + mFrameCallback = nullptr; + +- if (mPendingCommit) { +- CommitWaylandBuffer(); +- } ++ CommitWaylandBuffer(); + } + + void WindowSurfaceWayland::DelayedCommitHandler() { +@@ -1089,9 +1136,7 @@ void WindowSurfaceWayland::DelayedCommit + free(mDelayedCommitHandle); + mDelayedCommitHandle = nullptr; + +- if (mPendingCommit) { +- CommitWaylandBuffer(); +- } ++ CommitWaylandBuffer(); + } + + } // namespace widget +diff -up firefox-69.0/widget/gtk/WindowSurfaceWayland.h.mozilla-1580152 firefox-69.0/widget/gtk/WindowSurfaceWayland.h +--- firefox-69.0/widget/gtk/WindowSurfaceWayland.h.mozilla-1580152 2019-09-16 10:43:50.214742949 +0200 ++++ firefox-69.0/widget/gtk/WindowSurfaceWayland.h 2019-09-16 11:09:05.651780592 +0200 +@@ -17,6 +17,8 @@ + namespace mozilla { + namespace widget { + ++class WindowSurfaceWayland; ++ + // Allocates and owns shared memory for Wayland drawing surface + class WaylandShmPool { + public: +@@ -69,20 +71,22 @@ class WindowBackBuffer { + + static gfx::SurfaceFormat GetSurfaceFormat() { return mFormat; } + +- nsWaylandDisplay* GetWaylandDisplay() { return mWaylandDisplay; }; ++ nsWaylandDisplay* GetWaylandDisplay(); + +- WindowBackBuffer(nsWaylandDisplay* aWaylandDisplay) +- : mWaylandDisplay(aWaylandDisplay){}; ++ WindowBackBuffer(WindowSurfaceWayland* aWindowSurfaceWayland) ++ : mWindowSurfaceWayland(aWindowSurfaceWayland){}; + virtual ~WindowBackBuffer(){}; + ++ protected: ++ WindowSurfaceWayland* mWindowSurfaceWayland; ++ + private: + static gfx::SurfaceFormat mFormat; +- nsWaylandDisplay* mWaylandDisplay; + }; + + class WindowBackBufferShm : public WindowBackBuffer { + public: +- WindowBackBufferShm(nsWaylandDisplay* aWaylandDisplay, int aWidth, ++ WindowBackBufferShm(WindowSurfaceWayland* aWindowSurfaceWayland, int aWidth, + int aHeight); + ~WindowBackBufferShm(); + +@@ -121,8 +125,8 @@ class WindowBackBufferShm : public Windo + + class WindowBackBufferDMABuf : public WindowBackBuffer { + public: +- WindowBackBufferDMABuf(nsWaylandDisplay* aWaylandDisplay, int aWidth, +- int aHeight); ++ WindowBackBufferDMABuf(WindowSurfaceWayland* aWindowSurfaceWayland, ++ int aWidth, int aHeight); + ~WindowBackBufferDMABuf(); + + bool IsAttached(); +@@ -175,6 +179,9 @@ class WindowSurfaceWayland : public Wind + void Commit(const LayoutDeviceIntRegion& aInvalidRegion) final; + void FrameCallbackHandler(); + void DelayedCommitHandler(); ++ void CommitWaylandBuffer(); ++ ++ nsWaylandDisplay* GetWaylandDisplay() { return mWaylandDisplay; }; + + private: + WindowBackBuffer* CreateWaylandBuffer(int aWidth, int aHeight); +@@ -185,10 +192,9 @@ class WindowSurfaceWayland : public Wind + + already_AddRefed LockImageSurface( + const gfx::IntSize& aLockSize); +- bool CommitImageSurfaceToWaylandBuffer( +- const LayoutDeviceIntRegion& aRegion, +- LayoutDeviceIntRegion& aWaylandBufferDamage); +- void CommitWaylandBuffer(); ++ ++ void CacheImageSurface(const LayoutDeviceIntRegion& aRegion); ++ bool CommitImageCacheToWaylandBuffer(); + + void DrawDelayedImageCommits(gfx::DrawTarget* aDrawTarget, + LayoutDeviceIntRegion& aWaylandBufferDamage); +@@ -205,12 +211,13 @@ class WindowSurfaceWayland : public Wind + WindowBackBuffer* mBackupBuffer[BACK_BUFFER_NUM]; + wl_callback* mFrameCallback; + wl_surface* mLastCommittedSurface; +- MessageLoop* mDisplayThreadMessageLoop; + WindowSurfaceWayland** mDelayedCommitHandle; + RefPtr mImageSurface; + AutoTArray mDelayedImageCommits; ++ int64_t mLastCommitTime; + bool mDrawToWaylandBufferDirectly; +- bool mPendingCommit; ++ bool mBufferPendingCommit; ++ bool mBufferCommitAllowed; + bool mWholeWindowBufferDamage; + bool mBufferNeedsClear; + bool mIsMainThread;