From 211b25848ff715de01251179d246f8af84f61c01 Mon Sep 17 00:00:00 2001 From: Conn O'Griofa Date: Wed, 18 May 2022 18:20:33 +0100 Subject: [PATCH] platform/windows: add optional DwmFlush() call to improve Windows capture Invoke DwmFlush() before acquiring the next frame to alleviate visual stutter during mouse movement at the cost of constraining the capture rate to the host's monitor refresh. Disabled by default; enable via "dwmflush" boolean configuration parameter. --- CMakeLists.txt | 1 + docs/source/about/advanced_usage.rst | 19 +++++++++++++++++++ src_assets/common/assets/web/config.html | 14 +++++++++++++- sunshine/config.cpp | 8 +++++--- sunshine/config.h | 1 + sunshine/platform/windows/display.h | 3 ++- sunshine/platform/windows/display_base.cpp | 4 ++++ 7 files changed, 45 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c9a135f..8827b453 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,6 +122,7 @@ if(WIN32) ws2_32 d3d11 dxgi D3DCompiler setupapi + dwmapi ) set_source_files_properties(third-party/ViGEmClient/src/ViGEmClient.cpp PROPERTIES COMPILE_DEFINITIONS "UNICODE=1;ERROR_INVALID_DEVICE_OBJECT_PARAMETER=650") diff --git a/docs/source/about/advanced_usage.rst b/docs/source/about/advanced_usage.rst index 61c9e60f..e071ada5 100644 --- a/docs/source/about/advanced_usage.rst +++ b/docs/source/about/advanced_usage.rst @@ -333,6 +333,25 @@ Example 3840x1600, ] +dwmflush +^^^^^^^^ + +Description + Invoke DwmFlush() to sync screen capture to the Windows presentation interval. + + .. Caution:: Applies to Windows only. Alleviates visual stuttering during mouse movement, but causes the capture + rate to be limited to the host monitor's currently active refresh rate. + +Default + ``disabled`` + +Examples + + Windows + .. code-block:: text + + dwmflush = enabled + Audio ----- diff --git a/src_assets/common/assets/web/config.html b/src_assets/common/assets/web/config.html index 71372479..1d34512c 100644 --- a/src_assets/common/assets/web/config.html +++ b/src_assets/common/assets/web/config.html @@ -400,7 +400,18 @@ You can select the video card you want to stream:
The appropriate values can be found using the following command:
tools\dxgi-info.exe
-
+ + + +
+ + +
+ Improves capture latency during mouse movement.
+ Enabling this may prevent the client's FPS from exceeding the host monitor's active refresh rate.
@@ -832,6 +843,7 @@ this.config.key_rightalt_to_key_win || "disabled"; this.config.gamepad = this.config.gamepad || "x360"; this.config.upnp = this.config.upnp || "disabled"; + this.config.dwmflush = this.config.dwmflush || "disabled"; this.config.min_log_level = this.config.min_log_level || 2; this.config.origin_pin_allowed = this.config.origin_pin_allowed || "pc"; diff --git a/sunshine/config.cpp b/sunshine/config.cpp index e06a2801..ac1d9ccf 100644 --- a/sunshine/config.cpp +++ b/sunshine/config.cpp @@ -226,9 +226,10 @@ video_t video { 1, -1 }, // vt - {}, // encoder - {}, // adapter_name - {}, // output_name + {}, // encoder + {}, // adapter_name + {}, // output_name + false // dwmflush }; audio_t audio {}; @@ -735,6 +736,7 @@ void apply_config(std::unordered_map &&vars) { string_f(vars, "encoder", video.encoder); string_f(vars, "adapter_name", video.adapter_name); string_f(vars, "output_name", video.output_name); + bool_f(vars, "dwmflush", video.dwmflush); path_f(vars, "pkey", nvhttp.pkey); path_f(vars, "cert", nvhttp.cert); diff --git a/sunshine/config.h b/sunshine/config.h index 18313961..4ecb9f32 100644 --- a/sunshine/config.h +++ b/sunshine/config.h @@ -44,6 +44,7 @@ struct video_t { std::string encoder; std::string adapter_name; std::string output_name; + bool dwmflush; }; struct audio_t { diff --git a/sunshine/platform/windows/display.h b/sunshine/platform/windows/display.h index 37020fef..60539efc 100644 --- a/sunshine/platform/windows/display.h +++ b/sunshine/platform/windows/display.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -172,4 +173,4 @@ public: }; } // namespace platf::dxgi -#endif \ No newline at end of file +#endif diff --git a/sunshine/platform/windows/display_base.cpp b/sunshine/platform/windows/display_base.cpp index 02b08c37..12f8cad0 100644 --- a/sunshine/platform/windows/display_base.cpp +++ b/sunshine/platform/windows/display_base.cpp @@ -20,6 +20,10 @@ capture_e duplication_t::next_frame(DXGI_OUTDUPL_FRAME_INFO &frame_info, std::ch return capture_status; } + if(config::video.dwmflush) { + DwmFlush(); + } + auto status = dup->AcquireNextFrame(timeout.count(), &frame_info, res_p); switch(status) {