Skip to content

Commit f1bd628

Browse files
authored
core/renderer: Add GPU hotplug support (#8980)
1 parent fda5626 commit f1bd628

File tree

2 files changed

+47
-14
lines changed

2 files changed

+47
-14
lines changed

src/managers/eventLoop/EventLoopManager.cpp

+26-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <algorithm>
77
#include <limits>
8+
#include <ranges>
89

910
#include <sys/timerfd.h>
1011
#include <ctime>
@@ -20,8 +21,8 @@ CEventLoopManager::CEventLoopManager(wl_display* display, wl_event_loop* wlEvent
2021
}
2122

2223
CEventLoopManager::~CEventLoopManager() {
23-
for (auto const& eventSource : m_sWayland.aqEventSources) {
24-
wl_event_source_remove(eventSource);
24+
for (auto const& [_, eventSourceData] : aqEventSources) {
25+
wl_event_source_remove(eventSourceData.eventSource);
2526
}
2627

2728
if (m_sWayland.eventSource)
@@ -56,10 +57,8 @@ void CEventLoopManager::enterLoop() {
5657
if (const auto FD = g_pConfigWatcher->getInotifyFD(); FD >= 0)
5758
m_configWatcherInotifySource = wl_event_loop_add_fd(m_sWayland.loop, FD, WL_EVENT_READABLE, configWatcherWrite, nullptr);
5859

59-
aqPollFDs = g_pCompositor->m_pAqBackend->getPollFDs();
60-
for (auto const& fd : aqPollFDs) {
61-
m_sWayland.aqEventSources.emplace_back(wl_event_loop_add_fd(m_sWayland.loop, fd->fd, WL_EVENT_READABLE, aquamarineFDWrite, fd.get()));
62-
}
60+
syncPollFDs();
61+
m_sListeners.pollFDsChanged = g_pCompositor->m_pAqBackend->events.pollFDsChanged.registerListener([this](std::any d) { syncPollFDs(); });
6362

6463
// if we have a session, dispatch it to get the pending input devices
6564
if (g_pCompositor->m_pAqBackend->hasSession())
@@ -144,3 +143,24 @@ void CEventLoopManager::doLater(const std::function<void()>& fn) {
144143
},
145144
&m_sIdle);
146145
}
146+
147+
void CEventLoopManager::syncPollFDs() {
148+
auto aqPollFDs = g_pCompositor->m_pAqBackend->getPollFDs();
149+
150+
std::erase_if(aqEventSources, [&](const auto& item) {
151+
auto const& [fd, eventSourceData] = item;
152+
153+
// If no pollFD has the same fd, remove this event source
154+
const bool shouldRemove = std::ranges::none_of(aqPollFDs, [&](const auto& pollFD) { return pollFD->fd == fd; });
155+
156+
if (shouldRemove)
157+
wl_event_source_remove(eventSourceData.eventSource);
158+
159+
return shouldRemove;
160+
});
161+
162+
for (auto& fd : aqPollFDs | std::views::filter([&](SP<Aquamarine::SPollFD> fd) { return !aqEventSources.contains(fd->fd); })) {
163+
auto eventSource = wl_event_loop_add_fd(m_sWayland.loop, fd->fd, WL_EVENT_READABLE, aquamarineFDWrite, fd.get());
164+
aqEventSources[fd->fd] = {.pollFD = fd, .eventSource = eventSource};
165+
}
166+
}

src/managers/eventLoop/EventLoopManager.hpp

+21-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#pragma once
22

33
#include <condition_variable>
4+
#include <map>
45
#include <mutex>
56
#include <thread>
67
#include <wayland-server.h>
8+
#include "helpers/signal/Signal.hpp"
79

810
#include "EventLoopTimer.hpp"
911

@@ -36,24 +38,35 @@ class CEventLoopManager {
3638
};
3739

3840
private:
41+
// Manages the event sources after AQ pollFDs change.
42+
void syncPollFDs();
43+
44+
struct SEventSourceData {
45+
SP<Aquamarine::SPollFD> pollFD;
46+
wl_event_source* eventSource = nullptr;
47+
};
48+
3949
struct {
40-
wl_event_loop* loop = nullptr;
41-
wl_display* display = nullptr;
42-
wl_event_source* eventSource = nullptr;
43-
std::vector<wl_event_source*> aqEventSources;
50+
wl_event_loop* loop = nullptr;
51+
wl_display* display = nullptr;
52+
wl_event_source* eventSource = nullptr;
4453
} m_sWayland;
4554

4655
struct {
4756
std::vector<SP<CEventLoopTimer>> timers;
4857
int timerfd = -1;
4958
} m_sTimers;
5059

51-
SIdleData m_sIdle;
52-
std::vector<SP<Aquamarine::SPollFD>> aqPollFDs;
60+
SIdleData m_sIdle;
61+
std::map<int, SEventSourceData> aqEventSources;
62+
63+
struct {
64+
CHyprSignalListener pollFDsChanged;
65+
} m_sListeners;
5366

54-
wl_event_source* m_configWatcherInotifySource = nullptr;
67+
wl_event_source* m_configWatcherInotifySource = nullptr;
5568

5669
friend class CSyncTimeline;
5770
};
5871

59-
inline std::unique_ptr<CEventLoopManager> g_pEventLoopManager;
72+
inline std::unique_ptr<CEventLoopManager> g_pEventLoopManager;

0 commit comments

Comments
 (0)