Commit 77ee9e5d by Gustavo Noronha

HACK: use a separate thread to poll the Wayland socket

parent 38b78d1a
...@@ -7,11 +7,15 @@ ...@@ -7,11 +7,15 @@
#include <xdg-shell-unstable-v5-client-protocol.h> #include <xdg-shell-unstable-v5-client-protocol.h>
#include <xdg-shell-unstable-v6-client-protocol.h> #include <xdg-shell-unstable-v6-client-protocol.h>
#include <signal.h>
#include <poll.h>
#include "base/bind.h" #include "base/bind.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "ui/ozone/platform/wayland/wayland_object.h" #include "ui/ozone/platform/wayland/wayland_object.h"
#include "ui/ozone/platform/wayland/wayland_window.h" #include "ui/ozone/platform/wayland/wayland_window.h"
...@@ -36,6 +40,10 @@ WaylandConnection::WaylandConnection() : controller_(FROM_HERE) {} ...@@ -36,6 +40,10 @@ WaylandConnection::WaylandConnection() : controller_(FROM_HERE) {}
WaylandConnection::~WaylandConnection() { WaylandConnection::~WaylandConnection() {
DCHECK(window_map_.empty()); DCHECK(window_map_.empty());
// Clear display explicitly to signal the poll in our thread
// that it should wake up and go away.
display_.reset(nullptr);
} }
bool WaylandConnection::Initialize() { bool WaylandConnection::Initialize() {
...@@ -84,6 +92,32 @@ bool WaylandConnection::Initialize() { ...@@ -84,6 +92,32 @@ bool WaylandConnection::Initialize() {
return true; return true;
} }
void WaylandConnection::WaylandEventsThread() {
struct pollfd to_poll = { wl_display_get_fd(display_.get()), POLLIN, 0 };
for (;;) {
if (!display_)
break;
if (wl_display_prepare_read(display_.get()) != 0) {
ui_task_runner_->PostTask(
FROM_HERE, base::Bind(&WaylandConnection::DispatchEvents, this));
continue;
}
int events = poll(&to_poll, 1, 10);
if (events == 0 || !(to_poll.revents & POLLIN)) {
wl_display_cancel_read(display_.get());
continue;
} else if (events < 0 || (to_poll.revents & POLLHUP)) {
break;
}
wl_display_read_events(display_.get());
ui_task_runner_->PostTask(
FROM_HERE, base::Bind(&WaylandConnection::DispatchEvents, this));
}
}
bool WaylandConnection::StartProcessingEvents() { bool WaylandConnection::StartProcessingEvents() {
if (watching_) if (watching_)
return true; return true;
...@@ -92,15 +126,27 @@ bool WaylandConnection::StartProcessingEvents() { ...@@ -92,15 +126,27 @@ bool WaylandConnection::StartProcessingEvents() {
wl_display_flush(display_.get()); wl_display_flush(display_.get());
DCHECK(base::MessageLoopForUI::IsCurrent()); DCHECK(base::MessageLoopForUI::IsCurrent());
if (!base::MessageLoopForUI::current()->WatchFileDescriptor(
wl_display_get_fd(display_.get()), true, ui_task_runner_ = base::MessageLoopForUI::current()->task_runner();
base::MessagePumpLibevent::WATCH_READ, &controller_, this))
return false; thread_ = base::MakeUnique<base::Thread>("WaylandThread");
base::Thread::Options thread_options(base::MessageLoop::TYPE_UI, 0);
thread_options.priority = base::ThreadPriority::NORMAL;
CHECK(thread_->StartWithOptions(thread_options));
thread_->task_runner()->PostTask(
FROM_HERE, base::Bind(&WaylandConnection::WaylandEventsThread, this));
watching_ = true; watching_ = true;
return true; return true;
} }
void WaylandConnection::DispatchEvents() {
wl_display_dispatch_pending(display_.get());
for (const auto& window : window_map_)
window.second->ApplyPendingBounds();
}
void WaylandConnection::ScheduleFlush() { void WaylandConnection::ScheduleFlush() {
if (scheduled_flush_ || !watching_) if (scheduled_flush_ || !watching_)
return; return;
...@@ -152,14 +198,6 @@ void WaylandConnection::DispatchUiEvent(Event* event) { ...@@ -152,14 +198,6 @@ void WaylandConnection::DispatchUiEvent(Event* event) {
PlatformEventSource::DispatchEvent(event); PlatformEventSource::DispatchEvent(event);
} }
void WaylandConnection::OnFileCanReadWithoutBlocking(int fd) {
wl_display_dispatch(display_.get());
for (const auto& window : window_map_)
window.second->ApplyPendingBounds();
}
void WaylandConnection::OnFileCanWriteWithoutBlocking(int fd) {}
const std::vector<std::unique_ptr<WaylandOutput>>& const std::vector<std::unique_ptr<WaylandOutput>>&
WaylandConnection::GetOutputList() const { WaylandConnection::GetOutputList() const {
return output_list_; return output_list_;
......
...@@ -16,12 +16,17 @@ ...@@ -16,12 +16,17 @@
#include "ui/ozone/platform/wayland/wayland_pointer.h" #include "ui/ozone/platform/wayland/wayland_pointer.h"
#include "ui/ozone/platform/wayland/wayland_touch.h" #include "ui/ozone/platform/wayland/wayland_touch.h"
namespace base {
class SingleThreadTaskRunner;
class Thread;
}
namespace ui { namespace ui {
class WaylandWindow; class WaylandWindow;
class WaylandConnection : public PlatformEventSource, class WaylandConnection : public PlatformEventSource,
public base::MessagePumpLibevent::Watcher { public base::RefCountedThreadSafe<WaylandConnection> {
public: public:
WaylandConnection(); WaylandConnection();
~WaylandConnection() override; ~WaylandConnection() override;
...@@ -65,10 +70,6 @@ class WaylandConnection : public PlatformEventSource, ...@@ -65,10 +70,6 @@ class WaylandConnection : public PlatformEventSource,
// PlatformEventSource // PlatformEventSource
void OnDispatcherListChanged() override; void OnDispatcherListChanged() override;
// base::MessagePumpLibevent::Watcher
void OnFileCanReadWithoutBlocking(int fd) override;
void OnFileCanWriteWithoutBlocking(int fd) override;
// wl_registry_listener // wl_registry_listener
static void Global(void* data, static void Global(void* data,
wl_registry* registry, wl_registry* registry,
...@@ -87,6 +88,9 @@ class WaylandConnection : public PlatformEventSource, ...@@ -87,6 +88,9 @@ class WaylandConnection : public PlatformEventSource,
// xdg_shell_listener // xdg_shell_listener
static void Ping(void* data, xdg_shell* shell, uint32_t serial); static void Ping(void* data, xdg_shell* shell, uint32_t serial);
void WaylandEventsThread();
void DispatchEvents();
#if defined(USE_ILM) #if defined(USE_ILM)
// serverinfo_listener // serverinfo_listener
static void ServerInfo(void* data, struct serverinfo* serverinfo, uint32_t client_handle); static void ServerInfo(void* data, struct serverinfo* serverinfo, uint32_t client_handle);
...@@ -120,6 +124,9 @@ class WaylandConnection : public PlatformEventSource, ...@@ -120,6 +124,9 @@ class WaylandConnection : public PlatformEventSource,
// press event. It is used to create new subsurfaces. // press event. It is used to create new subsurfaces.
uint32_t serial_ = 0; uint32_t serial_ = 0;
std::unique_ptr<base::Thread> thread_;
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
#if defined(USE_ILM) #if defined(USE_ILM)
uint32_t connect_id_ = 0; uint32_t connect_id_ = 0;
#endif #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment