kalev / rpms / firefox

Forked from rpms/firefox 4 years ago
Clone
Blob Blame History Raw
diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -70,6 +70,10 @@
 #  include "mozilla/gfx/DeviceManagerDx.h"
 #endif
 
+#ifdef MOZ_WAYLAND
+#  include "mozilla/widget/nsWaylandDisplayShutdown.h"
+#endif
+
 #include "nsGkAtoms.h"
 #include "gfxPlatformFontList.h"
 #include "gfxContext.h"
@@ -1276,6 +1280,9 @@
       layers::PaintThread::Shutdown();
     }
   } else if (XRE_IsParentProcess()) {
+#ifdef MOZ_WAYLAND
+    widget::WaylandDisplayShutdown();
+#endif
     gfx::VRManagerChild::ShutDown();
     layers::CompositorManagerChild::Shutdown();
     layers::ImageBridgeChild::ShutDown();
diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp
--- a/widget/gtk/WindowSurfaceWayland.cpp
+++ b/widget/gtk/WindowSurfaceWayland.cpp
@@ -144,6 +144,8 @@
 (wl_buffer/wl_surface).
 */
 
+#define EVENT_LOOP_DELAY (1000 / 240)
+
 #define BUFFER_BPP 4
 gfx::SurfaceFormat WindowBackBuffer::mFormat = gfx::SurfaceFormat::B8G8R8A8;
 
diff --git a/widget/gtk/moz.build b/widget/gtk/moz.build
--- a/widget/gtk/moz.build
+++ b/widget/gtk/moz.build
@@ -101,6 +101,9 @@
         'nsWaylandDisplay.cpp',
         'WindowSurfaceWayland.cpp',
     ]
+    EXPORTS.mozilla.widget += [
+        'nsWaylandDisplayShutdown.h'
+    ]
 
 if CONFIG['ACCESSIBILITY']:
     UNIFIED_SOURCES += [
diff --git a/widget/gtk/nsAppShell.cpp b/widget/gtk/nsAppShell.cpp
--- a/widget/gtk/nsAppShell.cpp
+++ b/widget/gtk/nsAppShell.cpp
@@ -27,6 +27,9 @@
 #include "ScreenHelperGTK.h"
 #include "HeadlessScreenHelper.h"
 #include "mozilla/widget/ScreenManager.h"
+#ifdef MOZ_WAYLAND
+#  include "nsWaylandDisplay.h"
+#endif
 
 using mozilla::LazyLogModule;
 using mozilla::Unused;
@@ -267,5 +270,9 @@
 }
 
 bool nsAppShell::ProcessNextNativeEvent(bool mayWait) {
-  return g_main_context_iteration(nullptr, mayWait);
+  bool ret = g_main_context_iteration(nullptr, mayWait);
+#ifdef MOZ_WAYLAND
+  WaylandDispatchDisplays();
+#endif
+  return ret;
 }
diff --git a/widget/gtk/nsWaylandDisplay.h b/widget/gtk/nsWaylandDisplay.h
--- a/widget/gtk/nsWaylandDisplay.h
+++ b/widget/gtk/nsWaylandDisplay.h
@@ -14,10 +14,6 @@
 namespace mozilla {
 namespace widget {
 
-// TODO: Bug 1467125 - We need to integrate wl_display_dispatch_queue_pending()
-// with compositor event loop.
-#define EVENT_LOOP_DELAY (1000 / 240)
-
 // Our general connection to Wayland display server,
 // holds our display connection and runs event loop.
 class nsWaylandDisplay {
@@ -25,9 +21,10 @@
   explicit nsWaylandDisplay(wl_display* aDisplay);
   virtual ~nsWaylandDisplay();
 
-  bool DisplayLoop();
+  bool DispatchEventQueue();
   bool Matches(wl_display* aDisplay);
 
+  MessageLoop* GetDispatcherThreadLoop() { return mDispatcherThreadLoop; }
   wl_display* GetDisplay() { return mDisplay; };
   wl_event_queue* GetEventQueue() { return mEventQueue; };
   wl_subcompositor* GetSubcompositor(void) { return mSubcompositor; };
@@ -47,7 +44,10 @@
   void SetPrimarySelectionDeviceManager(
       gtk_primary_selection_device_manager* aPrimarySelectionDeviceManager);
 
+  void Shutdown();
+
  private:
+  MessageLoop* mDispatcherThreadLoop;
   PRThread* mThreadId;
   wl_display* mDisplay;
   wl_event_queue* mEventQueue;
@@ -59,6 +59,7 @@
   wl_registry* mRegistry;
 };
 
+void WaylandDispatchDisplays();
 nsWaylandDisplay* WaylandDisplayGet(GdkDisplay* aGdkDisplay = nullptr);
 
 }  // namespace widget
diff --git a/widget/gtk/nsWaylandDisplay.cpp b/widget/gtk/nsWaylandDisplay.cpp
--- a/widget/gtk/nsWaylandDisplay.cpp
+++ b/widget/gtk/nsWaylandDisplay.cpp
@@ -21,6 +21,15 @@
 static nsWaylandDisplay *gWaylandDisplays[MAX_DISPLAY_CONNECTIONS];
 static StaticMutex gWaylandDisplaysMutex;
 
+void WaylandDisplayShutdown() {
+  StaticMutexAutoLock lock(gWaylandDisplaysMutex);
+  for (auto &display : gWaylandDisplays) {
+    if (display) {
+      display->Shutdown();
+    }
+  }
+}
+
 static void ReleaseDisplaysAtExit() {
   for (int i = 0; i < MAX_DISPLAY_CONNECTIONS; i++) {
     delete gWaylandDisplays[i];
@@ -28,6 +37,10 @@
   }
 }
 
+static void DispatchDisplay(nsWaylandDisplay *aDisplay) {
+  aDisplay->DispatchEventQueue();
+}
+
 // Each thread which is using wayland connection (wl_display) has to operate
 // its own wl_event_queue. Main Firefox thread wl_event_queue is handled
 // by Gtk main loop, other threads/wl_event_queue has to be handled by us.
@@ -35,7 +48,15 @@
 // nsWaylandDisplay is our interface to wayland compositor. It provides wayland
 // global objects as we need (wl_display, wl_shm) and operates wl_event_queue on
 // compositor (not the main) thread.
-static void WaylandDisplayLoop(wl_display *aDisplay);
+void WaylandDispatchDisplays() {
+  StaticMutexAutoLock lock(gWaylandDisplaysMutex);
+  for (auto &display : gWaylandDisplays) {
+    if (display && display->GetDispatcherThreadLoop()) {
+      display->GetDispatcherThreadLoop()->PostTask(NewRunnableFunction(
+          "WaylandDisplayDispatch", &DispatchDisplay, display));
+    }
+  }
+}
 
 // Get WaylandDisplay for given wl_display and actual calling thread.
 static nsWaylandDisplay *WaylandDisplayGetLocked(GdkDisplay *aGdkDisplay,
@@ -73,27 +94,6 @@
   return WaylandDisplayGetLocked(aGdkDisplay, lock);
 }
 
-static void WaylandDisplayLoopLocked(wl_display *aDisplay,
-                                     const StaticMutexAutoLock &) {
-  for (auto &display : gWaylandDisplays) {
-    if (display && display->Matches(aDisplay)) {
-      if (display->DisplayLoop()) {
-        MessageLoop::current()->PostDelayedTask(
-            NewRunnableFunction("WaylandDisplayLoop", &WaylandDisplayLoop,
-                                aDisplay),
-            EVENT_LOOP_DELAY);
-      }
-      break;
-    }
-  }
-}
-
-static void WaylandDisplayLoop(wl_display *aDisplay) {
-  MOZ_ASSERT(!NS_IsMainThread());
-  StaticMutexAutoLock lock(gWaylandDisplaysMutex);
-  WaylandDisplayLoopLocked(aDisplay, lock);
-}
-
 void nsWaylandDisplay::SetShm(wl_shm *aShm) { mShm = aShm; }
 
 void nsWaylandDisplay::SetSubcompositor(wl_subcompositor *aSubcompositor) {
@@ -158,7 +158,7 @@
 static const struct wl_registry_listener registry_listener = {
     global_registry_handler, global_registry_remover};
 
-bool nsWaylandDisplay::DisplayLoop() {
+bool nsWaylandDisplay::DispatchEventQueue() {
   wl_display_dispatch_queue_pending(mDisplay, mEventQueue);
   return true;
 }
@@ -168,7 +168,8 @@
 }
 
 nsWaylandDisplay::nsWaylandDisplay(wl_display *aDisplay)
-    : mThreadId(PR_GetCurrentThread()),
+    : mDispatcherThreadLoop(nullptr),
+      mThreadId(PR_GetCurrentThread()),
       mDisplay(aDisplay),
       mEventQueue(nullptr),
       mDataDeviceManager(nullptr),
@@ -186,15 +187,16 @@
     wl_display_roundtrip(mDisplay);
     wl_display_roundtrip(mDisplay);
   } else {
+    mDispatcherThreadLoop = MessageLoop::current();
     mEventQueue = wl_display_create_queue(mDisplay);
-    MessageLoop::current()->PostTask(NewRunnableFunction(
-        "WaylandDisplayLoop", &WaylandDisplayLoop, mDisplay));
     wl_proxy_set_queue((struct wl_proxy *)mRegistry, mEventQueue);
     wl_display_roundtrip_queue(mDisplay, mEventQueue);
     wl_display_roundtrip_queue(mDisplay, mEventQueue);
   }
 }
 
+void nsWaylandDisplay::Shutdown() { mDispatcherThreadLoop = nullptr; }
+
 nsWaylandDisplay::~nsWaylandDisplay() {
   // Owned by Gtk+, we don't need to release
   mDisplay = nullptr;
diff --git a/widget/gtk/nsWaylandDisplayShutdown.h b/widget/gtk/nsWaylandDisplayShutdown.h
new file mode 100644
--- /dev/null
+++ b/widget/gtk/nsWaylandDisplayShutdown.h
@@ -0,0 +1,19 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:expandtab:shiftwidth=4:tabstop=4:
+ */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef __MOZ_WAYLAND_DISPLAY_SHUTDOWN_H__
+#define __MOZ_WAYLAND_DISPLAY_SHUTDOWN_H__
+
+namespace mozilla {
+namespace widget {
+
+void WaylandDisplayShutdown();
+
+}  // namespace widget
+}  // namespace mozilla
+
+#endif  // __MOZ_WAYLAND_DISPLAY_SHUTDOWN_H__