257 lines
8.0 KiB
Diff
257 lines
8.0 KiB
Diff
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__
|
|
|