renderer: fix frame sync (#13061)
* fix commit timing timer * fix surface state lock/unlock * debug state sync todos * debug solitary vrr
This commit is contained in:
parent
22fc8136a2
commit
82de66a030
9 changed files with 106 additions and 67 deletions
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue