diff options
| author | UjinT34 <41110182+UjinT34@users.noreply.github.com> | 2026-01-22 18:16:52 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-01-22 15:16:52 +0000 |
| commit | 82de66a030e6818ec3d21f49c8cdf9db31eebfa6 (patch) | |
| tree | 352d8b7df616b4a8038d14b578fa74357cc425a1 /src/protocols | |
| parent | 22fc8136a21676472b232f9462318e16b1d16745 (diff) | |
renderer: fix frame sync (#13061)
* fix commit timing timer
* fix surface state lock/unlock
* debug state sync todos
* debug solitary vrr
Diffstat (limited to 'src/protocols')
| -rw-r--r-- | src/protocols/CommitTiming.cpp | 8 | ||||
| -rw-r--r-- | src/protocols/Fifo.cpp | 45 | ||||
| -rw-r--r-- | src/protocols/core/Compositor.cpp | 4 | ||||
| -rw-r--r-- | src/protocols/types/SurfaceStateQueue.cpp | 3 | ||||
| -rw-r--r-- | src/protocols/types/SurfaceStateQueue.hpp | 2 |
5 files changed, 35 insertions, 27 deletions
diff --git a/src/protocols/CommitTiming.cpp b/src/protocols/CommitTiming.cpp index 2fcd8e9c..bce14f6b 100644 --- a/src/protocols/CommitTiming.cpp +++ b/src/protocols/CommitTiming.cpp @@ -32,9 +32,7 @@ CCommitTimerResource::CCommitTimerResource(UP<CWpCommitTimerV1>&& resource_, SP< const auto TIME_NOW = Time::steadyNow(); if (TIME_NOW > TIME) { - // TODO: should we err here? - // for now just do nothing I guess, thats some lag. - m_pendingTimeout = Time::steady_dur::min(); + m_pendingTimeout.reset(); } else m_pendingTimeout = TIME - TIME_NOW; }); @@ -56,6 +54,7 @@ CCommitTimerResource::CCommitTimerResource(UP<CWpCommitTimerV1>&& resource_, SP< m_surface->m_stateQueue.unlockFirst(LOCK_REASON_TIMER); }, nullptr); + g_pEventLoopManager->addTimer(timer); } else timer->updateTimeout(m_pendingTimeout); @@ -64,7 +63,8 @@ CCommitTimerResource::CCommitTimerResource(UP<CWpCommitTimerV1>&& resource_, SP< } CCommitTimerResource::~CCommitTimerResource() { - ; + if (m_timerPresent) + g_pEventLoopManager->removeTimer(timer); } bool CCommitTimerResource::good() { diff --git a/src/protocols/Fifo.cpp b/src/protocols/Fifo.cpp index d9f873c9..386327b5 100644 --- a/src/protocols/Fifo.cpp +++ b/src/protocols/Fifo.cpp @@ -34,35 +34,40 @@ CFifoResource::CFifoResource(UP<CWpFifoV1>&& resource_, SP<CWLSurfaceResource> s }); m_listeners.surfaceStateCommit = m_surface->m_events.stateCommit.listen([this](auto state) { + static const auto PPEND = CConfigValue<Hyprlang::INT>("debug:fifo_pending_workaround"); + if (!m_pending.surfaceLocked) return; - //#TODO: - // this feels wrong, but if we have no pending frames, presented might never come because - // we are waiting on the barrier to unlock and no damage is around. - if (m_surface->m_enteredOutputs.empty() && m_surface->m_hlSurface) { - for (auto& m : g_pCompositor->m_monitors) { - if (!m || !m->m_enabled) - continue; + if (*PPEND) { + //#TODO: + // this feels wrong, but if we have no pending frames, presented might never come because + // we are waiting on the barrier to unlock and no damage is around. + // unlock on timeout instead? + if (m_surface->m_enteredOutputs.empty() && m_surface->m_hlSurface) { + for (auto& m : g_pCompositor->m_monitors) { + if (!m || !m->m_enabled) + continue; + + auto box = m_surface->m_hlSurface->getSurfaceBoxGlobal(); + if (box && !box->intersection({m->m_position, m->m_size}).empty()) { + if (m->m_tearingState.activelyTearing) + return; // dont fifo lock on tearing. + + g_pCompositor->scheduleFrameForMonitor(m, Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME); + } + } + } else { + for (auto& m : m_surface->m_enteredOutputs) { + if (!m) + continue; - auto box = m_surface->m_hlSurface->getSurfaceBoxGlobal(); - if (box && !box->intersection({m->m_position, m->m_size}).empty()) { if (m->m_tearingState.activelyTearing) return; // dont fifo lock on tearing. - g_pCompositor->scheduleFrameForMonitor(m, Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME); + g_pCompositor->scheduleFrameForMonitor(m.lock(), Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME); } } - } else { - for (auto& m : m_surface->m_enteredOutputs) { - if (!m) - continue; - - if (m->m_tearingState.activelyTearing) - return; // dont fifo lock on tearing. - - g_pCompositor->scheduleFrameForMonitor(m.lock(), Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME); - } } // only lock once its mapped. diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp index c897bfe8..9fc44703 100644 --- a/src/protocols/core/Compositor.cpp +++ b/src/protocols/core/Compositor.cpp @@ -506,13 +506,13 @@ void CWLSurfaceResource::scheduleState(WP<SSurfaceState> state) { } } else if (state->buffer && state->buffer->isSynchronous()) { // synchronous (shm) buffers can be read immediately - m_stateQueue.unlock(state); + m_stateQueue.unlock(state, LOCK_REASON_FENCE); } else if (state->buffer && state->buffer->m_syncFd.isValid()) { // async buffer and is dmabuf, then we can wait on implicit fences g_pEventLoopManager->doOnReadable(std::move(state->buffer->m_syncFd), [state, whenReadable]() { whenReadable(state, LOCK_REASON_FENCE); }); } else { // state commit without a buffer. - m_stateQueue.unlock(state); + m_stateQueue.unlock(state, LOCK_REASON_FENCE); } } diff --git a/src/protocols/types/SurfaceStateQueue.cpp b/src/protocols/types/SurfaceStateQueue.cpp index c10b556f..348ac711 100644 --- a/src/protocols/types/SurfaceStateQueue.cpp +++ b/src/protocols/types/SurfaceStateQueue.cpp @@ -21,6 +21,7 @@ void CSurfaceStateQueue::dropState(const WP<SSurfaceState>& state) { } void CSurfaceStateQueue::lock(const WP<SSurfaceState>& weakState, eLockReason reason) { + ASSERT(reason != LOCK_REASON_NONE); auto it = find(weakState); if (it == m_queue.end()) return; @@ -29,6 +30,7 @@ void CSurfaceStateQueue::lock(const WP<SSurfaceState>& weakState, eLockReason re } void CSurfaceStateQueue::unlock(const WP<SSurfaceState>& state, eLockReason reason) { + ASSERT(reason != LOCK_REASON_NONE); auto it = find(state); if (it == m_queue.end()) return; @@ -38,6 +40,7 @@ void CSurfaceStateQueue::unlock(const WP<SSurfaceState>& state, eLockReason reas } void CSurfaceStateQueue::unlockFirst(eLockReason reason) { + ASSERT(reason != LOCK_REASON_NONE); for (auto& it : m_queue) { if ((it->lockMask & reason) != LOCK_REASON_NONE) { it->lockMask &= ~reason; diff --git a/src/protocols/types/SurfaceStateQueue.hpp b/src/protocols/types/SurfaceStateQueue.hpp index 1841ed20..8d9db7a5 100644 --- a/src/protocols/types/SurfaceStateQueue.hpp +++ b/src/protocols/types/SurfaceStateQueue.hpp @@ -15,7 +15,7 @@ class CSurfaceStateQueue { WP<SSurfaceState> enqueue(UP<SSurfaceState>&& state); void dropState(const WP<SSurfaceState>& state); void lock(const WP<SSurfaceState>& state, eLockReason reason); - void unlock(const WP<SSurfaceState>& state, eLockReason reason = LOCK_REASON_NONE); + void unlock(const WP<SSurfaceState>& state, eLockReason reason); void unlockFirst(eLockReason reason); void tryProcess(); |
