From fd563726f02427621dce3ca44ede689c2942890d Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 15 Apr 2022 23:21:52 -0500 Subject: [PATCH] Fix blocking presents in borderless windowed flip modes --- .../video/ffmpeg-renderers/dxva2.cpp | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/app/streaming/video/ffmpeg-renderers/dxva2.cpp b/app/streaming/video/ffmpeg-renderers/dxva2.cpp index d061c06b..828e1fc8 100644 --- a/app/streaming/video/ffmpeg-renderers/dxva2.cpp +++ b/app/streaming/video/ffmpeg-renderers/dxva2.cpp @@ -602,20 +602,10 @@ bool DXVA2Renderer::initializeDevice(SDL_Window* window, bool enableVsync) // to reduce latency by avoiding double v-syncing. d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - // If V-sync is enabled (not rendering faster than display), - // we can use FlipEx for more efficient swapping. - if (enableVsync) { - // D3DSWAPEFFECT_FLIPEX requires at least 2 back buffers to allow us to - // continue while DWM is waiting to render the surface to the display. - d3dpp.SwapEffect = D3DSWAPEFFECT_FLIPEX; - d3dpp.BackBufferCount = 2; - } - else { - // With V-sync off, we won't use FlipEx because that will block while - // DWM is waiting to render our surface (effectively behaving like V-Sync). - d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - d3dpp.BackBufferCount = 1; - } + // D3DSWAPEFFECT_FLIPEX requires at least 2 back buffers to allow us to + // continue while DWM is waiting to render the surface to the display. + d3dpp.SwapEffect = D3DSWAPEFFECT_FLIPEX; + d3dpp.BackBufferCount = 2; m_BlockingPresent = false; @@ -679,12 +669,17 @@ bool DXVA2Renderer::initializeDevice(SDL_Window* window, bool enableVsync) return false; } - hr = m_Device->SetMaximumFrameLatency(1); - if (FAILED(hr)) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "SetMaximumFrameLatency() failed: %x", - hr); - return false; + // We must not call this for flip swapchains. It will counterintuitively + // increase latency by forcing our Present() to block on DWM even when + // using D3DPRESENT_INTERVAL_IMMEDIATE. + if (d3dpp.SwapEffect != D3DSWAPEFFECT_FLIPEX) { + hr = m_Device->SetMaximumFrameLatency(1); + if (FAILED(hr)) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "SetMaximumFrameLatency() failed: %x", + hr); + return false; + } } return true;