Backed out 2 changesets (bug 1685055) for nsWaylandDisplay related bustage CLOSED TREE

Backed out changeset 813da913ec72 (bug 1685055)
Backed out changeset c46c76db0a48 (bug 1685055)
This commit is contained in:
Bogdan Tara 2021-01-11 22:27:24 +02:00
Родитель b2b774c844
Коммит 0545759f73
4 изменённых файлов: 88 добавлений и 14 удалений

Просмотреть файл

@ -83,6 +83,10 @@
# include "mozilla/WindowsVersion.h"
#endif
#ifdef MOZ_WAYLAND
# include "mozilla/widget/nsWaylandDisplay.h"
#endif
#include "nsGkAtoms.h"
#include "gfxPlatformFontList.h"
#include "gfxContext.h"
@ -1349,6 +1353,10 @@ void gfxPlatform::ShutdownLayersIPC() {
}
sLayersIPCIsUp = false;
#ifdef MOZ_WAYLAND
widget::WaylandDisplayShutdown();
#endif
if (XRE_IsContentProcess()) {
gfx::VRManagerChild::ShutDown();
// cf bug 1215265.

Просмотреть файл

@ -14,6 +14,8 @@
#include "gfxPlatform.h"
#include "MozContainer.h"
#include "nsTArray.h"
#include "base/message_loop.h" // for MessageLoop
#include "base/task.h" // for NewRunnableMethod, etc
#include "mozilla/ScopeExit.h"
#include "mozilla/StaticPrefs_widget.h"

Просмотреть файл

@ -25,13 +25,42 @@ namespace widget {
static RefPtr<nsWaylandDisplay> gWaylandDisplays[MAX_DISPLAY_CONNECTIONS];
static StaticMutex gWaylandDisplayArrayWriteMutex;
// Dispatch events to Compositor/Render queues
void WaylandDispatchDisplays() {
MOZ_ASSERT(NS_IsMainThread(),
"WaylandDispatchDisplays() is supposed to run in main thread");
void WaylandDisplayShutdown() {
for (auto& display : gWaylandDisplays) {
if (display) {
display->DispatchEventQueue();
display->ShutdownThreadLoop();
}
}
}
static void DispatchDisplay(RefPtr<nsWaylandDisplay> aDisplay) {
// We can't use aDisplay directly here as it can be already released.
// Instead look for aDisplay in gWaylandDisplays and dispatch it only when
// it's still active.
for (auto& display : gWaylandDisplays) {
if (display == aDisplay) {
aDisplay->DispatchEventQueue();
return;
}
}
NS_WARNING("DispatchDisplay was called for released display!");
}
// 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.
//
// 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.
void WaylandDispatchDisplays() {
for (auto& display : gWaylandDisplays) {
if (display) {
MessageLoop* loop = display->GetThreadLoop();
if (loop) {
loop->PostTask(NewRunnableFunction("WaylandDisplayDispatch",
&DispatchDisplay, display));
}
}
}
}
@ -184,9 +213,7 @@ static const struct wl_registry_listener registry_listener = {
global_registry_handler, global_registry_remover};
bool nsWaylandDisplay::DispatchEventQueue() {
if (mEventQueue) {
wl_display_dispatch_queue_pending(mDisplay, mEventQueue);
}
wl_display_dispatch_queue_pending(mDisplay, mEventQueue);
return true;
}
@ -230,10 +257,22 @@ void nsWaylandDisplay::SyncBegin() {
wl_display_flush(mDisplay);
}
static void WaylandDisplayQueueSyncBegin(RefPtr<nsWaylandDisplay> aDisplay) {
for (auto& display : gWaylandDisplays) {
if (display == aDisplay) {
display->SyncBegin();
return;
}
}
NS_WARNING("DispatchDisplay was called for released display!");
}
void nsWaylandDisplay::QueueSyncBegin() {
NS_DispatchToMainThread(
NS_NewRunnableFunction("nsWaylandDisplay::QueueSyncBegin",
[this]() -> void { this->SyncBegin(); }));
MessageLoop* loop = GetThreadLoop();
if (loop) {
loop->PostTask(NewRunnableFunction("WaylandSyncBegin",
&WaylandDisplayQueueSyncBegin, this));
}
}
void nsWaylandDisplay::WaitForSyncEnd() {
@ -243,8 +282,6 @@ void nsWaylandDisplay::WaitForSyncEnd() {
}
while (mSyncCallback != nullptr) {
// TODO: wl_display_dispatch_queue() should not be called while
// glib main loop is iterated at nsAppShell::ProcessNextNativeEvent().
if (wl_display_dispatch_queue(mDisplay, mEventQueue) == -1) {
NS_WARNING("wl_display_dispatch_queue failed!");
SyncEnd();
@ -257,8 +294,23 @@ bool nsWaylandDisplay::Matches(wl_display* aDisplay) {
return mThreadId == PR_GetCurrentThread() && aDisplay == mDisplay;
}
class nsWaylandDisplayLoopObserver : public MessageLoop::DestructionObserver {
public:
explicit nsWaylandDisplayLoopObserver(nsWaylandDisplay* aWaylandDisplay)
: mDisplay(aWaylandDisplay){};
virtual void WillDestroyCurrentMessageLoop() override {
mDisplay->ShutdownThreadLoop();
mDisplay = nullptr;
delete this;
}
private:
nsWaylandDisplay* mDisplay;
};
nsWaylandDisplay::nsWaylandDisplay(wl_display* aDisplay, bool aLighWrapper)
: mThreadId(PR_GetCurrentThread()),
: mThreadLoop(nullptr),
mThreadId(PR_GetCurrentThread()),
mDisplay(aDisplay),
mEventQueue(nullptr),
mDataDeviceManager(nullptr),
@ -278,6 +330,11 @@ nsWaylandDisplay::nsWaylandDisplay(wl_display* aDisplay, bool aLighWrapper)
}
if (!NS_IsMainThread()) {
mThreadLoop = MessageLoop::current();
if (mThreadLoop) {
auto observer = new nsWaylandDisplayLoopObserver(this);
mThreadLoop->AddDestructionObserver(observer);
}
mEventQueue = wl_display_create_queue(mDisplay);
wl_proxy_set_queue((struct wl_proxy*)mRegistry, mEventQueue);
}
@ -293,6 +350,8 @@ nsWaylandDisplay::nsWaylandDisplay(wl_display* aDisplay, bool aLighWrapper)
}
}
void nsWaylandDisplay::ShutdownThreadLoop() { mThreadLoop = nullptr; }
nsWaylandDisplay::~nsWaylandDisplay() {
wl_registry_destroy(mRegistry);
mRegistry = nullptr;

Просмотреть файл

@ -75,11 +75,15 @@ class nsWaylandDisplay {
zwp_primary_selection_device_manager_v1* aPrimarySelectionDeviceManager);
void SetIdleInhibitManager(zwp_idle_inhibit_manager_v1* aIdleInhibitManager);
MessageLoop* GetThreadLoop() { return mThreadLoop; }
void ShutdownThreadLoop();
bool IsExplicitSyncEnabled() { return mExplicitSync; }
private:
~nsWaylandDisplay();
MessageLoop* mThreadLoop;
PRThread* mThreadId;
wl_display* mDisplay;
wl_event_queue* mEventQueue;
@ -97,6 +101,7 @@ class nsWaylandDisplay {
};
void WaylandDispatchDisplays();
void WaylandDisplayShutdown();
void WaylandDisplayRelease();
RefPtr<nsWaylandDisplay> WaylandDisplayGet(GdkDisplay* aGdkDisplay = nullptr);