Wait on our D3D11 swapchain before rendering to reduce latency

This commit is contained in:
Cameron Gutman
2022-04-07 21:46:48 -05:00
parent 474591c6a5
commit 6d3d51553b
4 changed files with 27 additions and 20 deletions
@@ -464,10 +464,6 @@ bool D3D11VARenderer::initialize(PDECODER_PARAMETERS params)
m_FrameWaitableObject = m_SwapChain->GetFrameLatencyWaitableObject();
SDL_assert(m_FrameWaitableObject != nullptr);
// Wait for the swap chain to be ready. This is required because we don't
// we're waiting after presenting in the general case, not before.
WaitForSingleObjectEx(m_FrameWaitableObject, 1000, FALSE);
}
else {
IDXGIDevice1* dxgiDevice;
@@ -582,6 +578,22 @@ void D3D11VARenderer::setHdrMode(bool enabled)
unlockContext(this);
}
void D3D11VARenderer::waitToRender()
{
if (m_FrameWaitableObject != nullptr) {
SDL_assert(m_Windowed);
SDL_assert(m_DecoderParams.enableVsync);
// Wait for the pipeline to be ready for the next frame in V-Sync mode.
//
// This callback happens before selecting the next frame to render, so
// we can wait for the previous frame to finish prior to picking the
// next one to display. This reduces the effective display latency
// by ensuring we always render the most recent frame immediately.
WaitForSingleObjectEx(m_FrameWaitableObject, 500, FALSE);
}
}
void D3D11VARenderer::renderFrame(AVFrame* frame)
{
// Acquire the context lock for rendering to prevent concurrent
@@ -669,22 +681,6 @@ void D3D11VARenderer::renderFrame(AVFrame* frame)
SDL_PushEvent(&event);
return;
}
if (m_FrameWaitableObject != nullptr) {
SDL_assert(m_Windowed);
SDL_assert(m_DecoderParams.enableVsync);
// Wait for the pipeline to be ready for the next frame in V-Sync mode.
//
// MSDN advises us to wait *before* doing any rendering operations,
// however that assumes the a typical game which will latch inputs,
// run the engine, draw, etc. after WaitForSingleObjectEx(). In our case,
// we actually want wait *after* our rendering operations, because our AVFrame
// is already set in stone by the time we enter this function. Waiting after
// presenting allows a more recent frame to be received before renderFrame()
// is called again.
WaitForSingleObjectEx(m_FrameWaitableObject, 1000, FALSE);
}
}
void D3D11VARenderer::renderOverlay(Overlay::OverlayType type)