diff options
| author | UjinT34 <41110182+UjinT34@users.noreply.github.com> | 2026-02-04 03:27:48 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-04 00:27:48 +0000 |
| commit | 1bc857b12c434b7255119de009a50237856a90b2 (patch) | |
| tree | 9520cdafe416155beb77e6cedf5420c42e32f6d6 /src/protocols/Fifo.cpp | |
| parent | cd7bdc7a43542370b5f57b97b25302a24abce126 (diff) | |
fifo: miscellaneous fifo fixes (#13136)
* LOGM: clang-tidy fix
* fix fifo state and scheduling
* disable fifo_pending_workaround by default
* fix tearing
* fix "empty" commit skipping
Diffstat (limited to 'src/protocols/Fifo.cpp')
| -rw-r--r-- | src/protocols/Fifo.cpp | 90 |
1 files changed, 53 insertions, 37 deletions
diff --git a/src/protocols/Fifo.cpp b/src/protocols/Fifo.cpp index 386327b5..8f842593 100644 --- a/src/protocols/Fifo.cpp +++ b/src/protocols/Fifo.cpp @@ -18,7 +18,8 @@ CFifoResource::CFifoResource(UP<CWpFifoV1>&& resource_, SP<CWLSurfaceResource> s return; } - m_pending.barrierSet = true; + m_surface->m_pending.barrierSet = true; + m_surface->m_pending.updated.bits.fifo = true; }); m_resource->setWaitBarrier([this](CWpFifoV1* r) { @@ -27,54 +28,37 @@ CFifoResource::CFifoResource(UP<CWpFifoV1>&& resource_, SP<CWLSurfaceResource> s return; } - if (!m_pending.barrierSet) + if (!m_surface->m_current.barrierSet) { + // that might mean an empty commit with a barrier_set alone + static const auto PPEND = CConfigValue<Hyprlang::INT>("debug:fifo_pending_workaround"); + if (!m_surface->m_pending.fifoScheduled) + m_surface->m_pending.fifoScheduled = checkMonitors(*PPEND); + return; + } - m_pending.surfaceLocked = true; + m_surface->m_pending.surfaceLocked = true; }); m_listeners.surfaceStateCommit = m_surface->m_events.stateCommit.listen([this](auto state) { + if (!state || !state->surfaceLocked) + return; + 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. + // unlock on timeout instead? + if (!state->fifoScheduled) + state->fifoScheduled = checkMonitors(*PPEND); - 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; - - if (m->m_tearingState.activelyTearing) - return; // dont fifo lock on tearing. - - g_pCompositor->scheduleFrameForMonitor(m.lock(), Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME); - } - } - } + if (!state->fifoScheduled) + return; // only lock once its mapped. if (m_surface->m_mapped) m_surface->m_stateQueue.lock(state, LOCK_REASON_FIFO); - - m_pending = {}; }); } @@ -87,9 +71,41 @@ bool CFifoResource::good() { } void CFifoResource::presented() { + m_surface->m_current.barrierSet = false; m_surface->m_stateQueue.unlockFirst(LOCK_REASON_FIFO); } +bool CFifoResource::checkMonitors(bool needsSchedule) { + 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 false; // dont fifo lock on tearing. + + if (needsSchedule) + g_pCompositor->scheduleFrameForMonitor(m, Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME); + } + } + } else { + for (auto& m : m_surface->m_enteredOutputs) { + if (!m) + continue; + + if (m->m_tearingState.activelyTearing) + return false; // dont fifo lock on tearing. + + if (needsSchedule) + g_pCompositor->scheduleFrameForMonitor(m.lock(), Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME); + } + } + + return true; +} + CFifoManagerResource::CFifoManagerResource(UP<CWpFifoManagerV1>&& resource_) : m_resource(std::move(resource_)) { if UNLIKELY (!m_resource->resource()) return; |
