[idd] don't rebuild the monitor from inside the old monitor's context
Some checks are pending
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Waiting to run
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Waiting to run
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Waiting to run
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Waiting to run
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Waiting to run
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Waiting to run
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Waiting to run
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Waiting to run
build / module (push) Waiting to run
build / host-linux (push) Waiting to run
build / host-windows-cross (push) Waiting to run
build / host-windows-native (push) Waiting to run
build / idd (push) Waiting to run
build / obs (clang) (push) Waiting to run
build / obs (gcc) (push) Waiting to run
build / docs (push) Waiting to run

This commit is contained in:
Geoffrey McRae
2026-07-16 16:13:24 +10:00
parent fbf564f2e1
commit b97a0b79f1
2 changed files with 20 additions and 1 deletions

View File

@@ -390,8 +390,13 @@ void CIndirectDeviceContext::OnUnassignedSwapChain()
m_replugMonitor = false;
ReleaseSRWLockExclusive(&m_stateLock);
// Do NOT rebuild the monitor from inside this callback. Creating and arriving
// a new monitor here re-enters IddCx while the old monitor's swap-chain
// teardown is still unwinding on this thread, which leaves the new swap
// chain's surfaces lost/abandoned (DXGI_ERROR_ACCESS_LOST). Defer to the LGMP
// timer, matching how the departure is scheduled.
if (replug)
FinishInit(0);
InterlockedExchange(&m_finishInitQueued, 1);
}
void CIndirectDeviceContext::OnSwapChainLost()
@@ -913,6 +918,14 @@ void CIndirectDeviceContext::LGMPTimer()
return;
}
// Rebuild the monitor deferred from the IddCx unassign callback, off that
// callback's thread and after its swap-chain teardown has fully unwound.
if (InterlockedExchange(&m_finishInitQueued, 0))
{
FinishInit(0);
return;
}
LGMP_STATUS status;
if ((status = lgmpHostProcess(m_lgmp)) != LGMP_OK)
{