diff --git a/docs/source/about/advanced_usage.rst b/docs/source/about/advanced_usage.rst index e071ada5..e0903223 100644 --- a/docs/source/about/advanced_usage.rst +++ b/docs/source/about/advanced_usage.rst @@ -339,11 +339,12 @@ 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. + .. Caution:: Applies to Windows only. Alleviates visual stuttering during mouse movement. + If enabled, this feature will automatically deactivate if the client framerate exceeds + the host monitor's current refresh rate. Default - ``disabled`` + ``enabled`` Examples diff --git a/src_assets/common/assets/web/config.html b/src_assets/common/assets/web/config.html index 1d34512c..01954e76 100644 --- a/src_assets/common/assets/web/config.html +++ b/src_assets/common/assets/web/config.html @@ -410,8 +410,8 @@
- Improves capture latency during mouse movement.
- Enabling this may prevent the client's FPS from exceeding the host monitor's active refresh rate. + Improves capture latency/smoothness during mouse movement.
+ Disable if you encounter any VSync-related issues.
@@ -843,7 +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.dwmflush = this.config.dwmflush || "enabled"; 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 ac1d9ccf..21c27e2d 100644 --- a/sunshine/config.cpp +++ b/sunshine/config.cpp @@ -226,10 +226,10 @@ video_t video { 1, -1 }, // vt - {}, // encoder - {}, // adapter_name - {}, // output_name - false // dwmflush + {}, // encoder + {}, // adapter_name + {}, // output_name + true // dwmflush }; audio_t audio {}; diff --git a/sunshine/platform/windows/display.h b/sunshine/platform/windows/display.h index 60539efc..6a150135 100644 --- a/sunshine/platform/windows/display.h +++ b/sunshine/platform/windows/display.h @@ -96,6 +96,7 @@ class duplication_t { public: dup_t dup; bool has_frame {}; + bool use_dwmflush {}; capture_e next_frame(DXGI_OUTDUPL_FRAME_INFO &frame_info, std::chrono::milliseconds timeout, resource_t::pointer *res_p); capture_e reset(dup_t::pointer dup_p = dup_t::pointer()); diff --git a/sunshine/platform/windows/display_base.cpp b/sunshine/platform/windows/display_base.cpp index 12f8cad0..9ee9ad97 100644 --- a/sunshine/platform/windows/display_base.cpp +++ b/sunshine/platform/windows/display_base.cpp @@ -2,6 +2,7 @@ // Created by loki on 1/12/20. // +#include #include #include "display.h" @@ -20,7 +21,7 @@ capture_e duplication_t::next_frame(DXGI_OUTDUPL_FRAME_INFO &frame_info, std::ch return capture_status; } - if(config::video.dwmflush) { + if(use_dwmflush) { DwmFlush(); } @@ -217,6 +218,21 @@ int display_base_t::init(int framerate, const std::string &display_name) { << "Offset : "sv << offset_x << 'x' << offset_y << std::endl << "Virtual Desktop : "sv << env_width << 'x' << env_height; + // Enable DwmFlush() only if the current refresh rate can match the client framerate. + auto refresh_rate = framerate; + DWM_TIMING_INFO timing_info; + timing_info.cbSize = sizeof(timing_info); + + status = DwmGetCompositionTimingInfo(NULL, &timing_info); + if(FAILED(status)) { + BOOST_LOG(warning) << "Failed to detect active refresh rate."; + } + else { + refresh_rate = std::round((double)timing_info.rateRefresh.uiNumerator / (double)timing_info.rateRefresh.uiDenominator); + } + + dup.use_dwmflush = config::video.dwmflush && !(framerate > refresh_rate) ? true : false; + // Bump up thread priority { const DWORD flags = TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY;