summaryrefslogtreecommitdiff
path: root/mozilla-1656727.patch
diff options
context:
space:
mode:
Diffstat (limited to 'mozilla-1656727.patch')
-rw-r--r--mozilla-1656727.patch208
1 files changed, 208 insertions, 0 deletions
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<WindowSurfaceWayland**>(
+- 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<gfx::DrawTarget> 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<gfxImageSurface> mImageSurface;
+ AutoTArray<WindowImageSurface, 30> 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.
bgstack15