mirror of
https://github.com/hyprwm/hyprlock.git
synced 2025-01-26 04:19:48 +01:00
core: move wayland event reading into the poll thread (#655)
This was done, so that we can wl_display_prepare_read -> poll -> wl_display_read_events That fixes synchronization issues on nvidia proprietary drivers.
This commit is contained in:
parent
02639c2759
commit
d547d1d4e3
5 changed files with 46 additions and 41 deletions
|
@ -117,8 +117,6 @@ void CSessionLockSurface::onScaleUpdate() {
|
|||
}
|
||||
|
||||
void CSessionLockSurface::render() {
|
||||
Debug::log(TRACE, "render lock");
|
||||
|
||||
if (frameCallback || !readyForFrame) {
|
||||
needsFrame = true;
|
||||
return;
|
||||
|
@ -127,10 +125,16 @@ void CSessionLockSurface::render() {
|
|||
g_pAnimationManager->tick();
|
||||
const auto FEEDBACK = g_pRenderer->renderLock(*this);
|
||||
frameCallback = makeShared<CCWlCallback>(surface->sendFrame());
|
||||
frameCallback->setDone([this](CCWlCallback* r, uint32_t data) {
|
||||
frameCallback->setDone([this](CCWlCallback* r, uint32_t frameTime) {
|
||||
if (g_pHyprlock->m_bTerminate)
|
||||
return;
|
||||
|
||||
Debug::log(TRACE, "[{}] frame {}, Current fps: {:.2f}", output->stringPort, m_frames, 1000.f / (frameTime - m_lastFrameTime));
|
||||
|
||||
m_lastFrameTime = frameTime;
|
||||
|
||||
m_frames++;
|
||||
|
||||
onCallback();
|
||||
});
|
||||
|
||||
|
|
|
@ -42,6 +42,9 @@ class CSessionLockSurface {
|
|||
|
||||
bool needsFrame = false;
|
||||
|
||||
uint32_t m_lastFrameTime = 0;
|
||||
uint32_t m_frames = 0;
|
||||
|
||||
// wayland callbacks
|
||||
SP<CCWlCallback> frameCallback = nullptr;
|
||||
|
||||
|
|
|
@ -368,32 +368,45 @@ void CHyprlock::run() {
|
|||
|
||||
std::thread pollThr([this, &pollfds, fdcount]() {
|
||||
while (!m_bTerminate) {
|
||||
int ret = poll(pollfds, fdcount, 5000 /* 5 seconds, reasonable. Just in case we need to terminate and the signal fails */);
|
||||
bool preparedToRead = wl_display_prepare_read(m_sWaylandState.display) == 0;
|
||||
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
int events = 0;
|
||||
if (preparedToRead) {
|
||||
events = poll(pollfds, fdcount, 5000);
|
||||
|
||||
Debug::log(CRIT, "[core] Polling fds failed with {}", errno);
|
||||
attemptRestoreOnDeath();
|
||||
m_bTerminate = true;
|
||||
exit(1);
|
||||
}
|
||||
if (events < 0) {
|
||||
if (preparedToRead)
|
||||
wl_display_cancel_read(m_sWaylandState.display);
|
||||
|
||||
for (size_t i = 0; i < fdcount; ++i) {
|
||||
if (pollfds[i].revents & POLLHUP) {
|
||||
Debug::log(CRIT, "[core] Disconnected from pollfd id {}", i);
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
Debug::log(CRIT, "[core] Polling fds failed with {}", errno);
|
||||
attemptRestoreOnDeath();
|
||||
m_bTerminate = true;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < fdcount; ++i) {
|
||||
if (pollfds[i].revents & POLLHUP) {
|
||||
Debug::log(CRIT, "[core] Disconnected from pollfd id {}", i);
|
||||
attemptRestoreOnDeath();
|
||||
m_bTerminate = true;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
wl_display_read_events(m_sWaylandState.display);
|
||||
m_sLoopState.wlDispatched = false;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
if (events > 0 || !preparedToRead) {
|
||||
Debug::log(TRACE, "[core] got poll event");
|
||||
std::lock_guard<std::mutex> lg2(m_sLoopState.eventLoopMutex);
|
||||
std::unique_lock lk(m_sLoopState.eventLoopMutex);
|
||||
m_sLoopState.event = true;
|
||||
m_sLoopState.loopCV.notify_all();
|
||||
|
||||
m_sLoopState.wlDispatchCV.wait_for(lk, std::chrono::milliseconds(100), [this] { return m_sLoopState.wlDispatched; });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -439,30 +452,18 @@ void CHyprlock::run() {
|
|||
|
||||
m_sLoopState.event = false;
|
||||
|
||||
wl_display_dispatch_pending(m_sWaylandState.display);
|
||||
wl_display_flush(m_sWaylandState.display);
|
||||
|
||||
m_sLoopState.wlDispatched = true;
|
||||
m_sLoopState.wlDispatchCV.notify_all();
|
||||
|
||||
if (pollfds[1].revents & POLLIN /* dbus */) {
|
||||
while (dbusConn && dbusConn->processPendingEvent()) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (pollfds[0].revents & POLLIN /* wl */) {
|
||||
Debug::log(TRACE, "got wl event");
|
||||
wl_display_flush(m_sWaylandState.display);
|
||||
if (wl_display_prepare_read(m_sWaylandState.display) == 0) {
|
||||
wl_display_read_events(m_sWaylandState.display);
|
||||
wl_display_dispatch_pending(m_sWaylandState.display);
|
||||
} else {
|
||||
wl_display_dispatch(m_sWaylandState.display);
|
||||
}
|
||||
}
|
||||
|
||||
// finalize wayland dispatching. Dispatch pending on the queue
|
||||
int ret = 0;
|
||||
do {
|
||||
ret = wl_display_dispatch_pending(m_sWaylandState.display);
|
||||
wl_display_flush(m_sWaylandState.display);
|
||||
} while (ret > 0 && !m_bTerminate);
|
||||
|
||||
// do timers
|
||||
m_sLoopState.timersMutex.lock();
|
||||
auto timerscpy = m_vTimers;
|
||||
|
|
|
@ -151,6 +151,9 @@ class CHyprlock {
|
|||
std::condition_variable loopCV;
|
||||
bool event = false;
|
||||
|
||||
std::condition_variable wlDispatchCV;
|
||||
bool wlDispatched = false;
|
||||
|
||||
std::condition_variable timerCV;
|
||||
std::mutex timerRequestMutex;
|
||||
bool timerEvent = false;
|
||||
|
|
|
@ -198,8 +198,6 @@ CRenderer::CRenderer() {
|
|||
g_pAnimationManager->createAnimation(0.f, opacity, g_pConfigManager->m_AnimationTree.getConfig("fadeIn"));
|
||||
}
|
||||
|
||||
static int frames = 0;
|
||||
|
||||
//
|
||||
CRenderer::SRenderFeedback CRenderer::renderLock(const CSessionLockSurface& surf) {
|
||||
static auto* const PDISABLEBAR = (Hyprlang::INT* const*)g_pConfigManager->getValuePtr("general:disable_loading_bar");
|
||||
|
@ -238,10 +236,6 @@ CRenderer::SRenderFeedback CRenderer::renderLock(const CSessionLockSurface& surf
|
|||
}
|
||||
}
|
||||
|
||||
frames++;
|
||||
|
||||
Debug::log(TRACE, "frame {}", frames);
|
||||
|
||||
feedback.needsFrame = feedback.needsFrame || !asyncResourceGatherer->gathered;
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
|
Loading…
Reference in a new issue