mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-09 08:41:31 +00:00
[idd] capture: retire damage before copy submission
Retire candidate damage before submitting its publication copy. A fast completion callback can otherwise release and reuse the candidate while the publisher is still reading its fields and damage tail.
This commit is contained in:
@@ -1254,29 +1254,8 @@ bool CSwapChainProcessor::PublishNewestCandidate(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!copySlot->Execute())
|
// Retire the candidate damage before submission. The completion callback
|
||||||
{
|
// may run before Execute returns and make this candidate reusable.
|
||||||
AcquireSRWLockShared(&m_candidateLock);
|
|
||||||
const bool callbackPending =
|
|
||||||
candidate.state == CANDIDATE_PUBLISHING;
|
|
||||||
ReleaseSRWLockShared(&m_candidateLock);
|
|
||||||
if (callbackPending && !copySlot->HasSubmittedWork())
|
|
||||||
{
|
|
||||||
m_devContext->FailFrameBuffer(buffer.frameIndex);
|
|
||||||
SetFullPendingDamage();
|
|
||||||
ReleaseCandidate(candidateIndex);
|
|
||||||
}
|
|
||||||
m_devContext->ForceFrame();
|
|
||||||
|
|
||||||
AcquireSRWLockExclusive(&m_candidateLock);
|
|
||||||
for (FrameCandidate& held : m_candidates)
|
|
||||||
if (held.state == CANDIDATE_HELD)
|
|
||||||
held.state = CANDIDATE_READY;
|
|
||||||
ReleaseSRWLockExclusive(&m_candidateLock);
|
|
||||||
SignalCandidateState();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
AcquireSRWLockExclusive(&m_damageLock);
|
AcquireSRWLockExclusive(&m_damageLock);
|
||||||
if (candidate.nbDirtyRects)
|
if (candidate.nbDirtyRects)
|
||||||
memcpy(m_dirtyRects, candidate.dirtyRects,
|
memcpy(m_dirtyRects, candidate.dirtyRects,
|
||||||
@@ -1295,6 +1274,31 @@ bool CSwapChainProcessor::PublishNewestCandidate(
|
|||||||
}
|
}
|
||||||
ReleaseSRWLockExclusive(&m_damageLock);
|
ReleaseSRWLockExclusive(&m_damageLock);
|
||||||
|
|
||||||
|
if (!copySlot->Execute())
|
||||||
|
{
|
||||||
|
// The logical damage state was advanced before submission. Force a full
|
||||||
|
// repair whether submission failed or its callback reported the failure.
|
||||||
|
SetFullPendingDamage();
|
||||||
|
AcquireSRWLockShared(&m_candidateLock);
|
||||||
|
const bool callbackPending =
|
||||||
|
candidate.state == CANDIDATE_PUBLISHING;
|
||||||
|
ReleaseSRWLockShared(&m_candidateLock);
|
||||||
|
if (callbackPending && !copySlot->HasSubmittedWork())
|
||||||
|
{
|
||||||
|
m_devContext->FailFrameBuffer(buffer.frameIndex);
|
||||||
|
ReleaseCandidate(candidateIndex);
|
||||||
|
}
|
||||||
|
m_devContext->ForceFrame();
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&m_candidateLock);
|
||||||
|
for (FrameCandidate& held : m_candidates)
|
||||||
|
if (held.state == CANDIDATE_HELD)
|
||||||
|
held.state = CANDIDATE_READY;
|
||||||
|
ReleaseSRWLockExclusive(&m_candidateLock);
|
||||||
|
SignalCandidateState();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
m_devContext->CommitFrameBuffer(
|
m_devContext->CommitFrameBuffer(
|
||||||
buffer.frameIndex, schedule, periodic);
|
buffer.frameIndex, schedule, periodic);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user