diff options
author | Martin Stransky <stransky@redhat.com> | 2019-09-16 11:13:16 +0200 |
---|---|---|
committer | Martin Stransky <stransky@redhat.com> | 2019-09-16 11:13:16 +0200 |
commit | 9b804de1e9df481a535e369083ae9e255cbceae6 (patch) | |
tree | 49ad557b46294b431554012adc168184583e58e6 /mozilla-1580152.patch | |
parent | Fix for disappearing webrtc popups (diff) | |
download | librewolf-fedora-ff-9b804de1e9df481a535e369083ae9e255cbceae6.tar.gz librewolf-fedora-ff-9b804de1e9df481a535e369083ae9e255cbceae6.tar.bz2 librewolf-fedora-ff-9b804de1e9df481a535e369083ae9e255cbceae6.zip |
Added fixes for mozbz#1579823, mozbz#1580152
Diffstat (limited to 'mozilla-1580152.patch')
-rw-r--r-- | mozilla-1580152.patch | 617 |
1 files changed, 617 insertions, 0 deletions
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<nsWaylandDisplay*>(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_display*>(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<gfx::DrawTarget> 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<gfx::DrawTarget> 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<gfx::DrawTarget> 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<gfx::DrawTarget> 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<gfx::DrawTarget> 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<gfx::DrawTarget> 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<gfx::DrawTarget> 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<gfx::DrawTarget> 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<gfxImageSurface> mImageSurface; + AutoTArray<WindowImageSurface, 30> mDelayedImageCommits; ++ int64_t mLastCommitTime; + bool mDrawToWaylandBufferDirectly; +- bool mPendingCommit; ++ bool mBufferPendingCommit; ++ bool mBufferCommitAllowed; + bool mWholeWindowBufferDamage; + bool mBufferNeedsClear; + bool mIsMainThread; |