ui: scale the auto frame cap margin with the display refresh rate
This commit is contained in:
parent
79761cbdd5
commit
ae6ea8e925
3 changed files with 26 additions and 3 deletions
|
|
@ -222,6 +222,15 @@ class Window {
|
||||||
// readable from any thread (frame pacers, settings UI).
|
// readable from any thread (frame pacers, settings UI).
|
||||||
static float CachedDisplayRefreshHz();
|
static float CachedDisplayRefreshHz();
|
||||||
|
|
||||||
|
// Refresh-derived automatic frame cap for the given display refresh rate,
|
||||||
|
// 0 while the refresh is unknown. Presents run with tearing allowed, so on
|
||||||
|
// a VRR display any present arriving faster than the panel's minimum
|
||||||
|
// refresh period tears; the cap must sit far enough below the refresh rate
|
||||||
|
// that swap-to-present jitter cannot cross it. A fixed margin that is
|
||||||
|
// ample at 60 Hz is too thin at 144 Hz, so the margin scales with the
|
||||||
|
// refresh rate. Single source of the policy for pacers and settings UI.
|
||||||
|
static float AutoFrameCapHz(float refresh_hz);
|
||||||
|
|
||||||
// Round trips are not guaranteed to return the same results.
|
// Round trips are not guaranteed to return the same results.
|
||||||
static constexpr uint32_t ConvertSizeDpi(uint32_t size, uint32_t new_dpi, uint32_t old_dpi) {
|
static constexpr uint32_t ConvertSizeDpi(uint32_t size, uint32_t new_dpi, uint32_t old_dpi) {
|
||||||
// Always rounding up to prevent zero sizes (unless the input is zero) as
|
// Always rounding up to prevent zero sizes (unless the input is zero) as
|
||||||
|
|
|
||||||
|
|
@ -1351,10 +1351,12 @@ void SimpleSettingsDialog::BuildRows(std::vector<RowSpec>& rows, int category) {
|
||||||
"Auto tracks the current display and does exactly that. Frames above the "
|
"Auto tracks the current display and does exactly that. Frames above the "
|
||||||
"refresh rate cannot be shown and only make steady motion judder.";
|
"refresh rate cannot be shown and only make steady motion judder.";
|
||||||
if (FrameCapHasAuto()) {
|
if (FrameCapHasAuto()) {
|
||||||
const float hz = rex::ui::Window::CachedDisplayRefreshHz();
|
// Same policy the guest pacer applies (see Window::AutoFrameCapHz).
|
||||||
|
const float auto_cap =
|
||||||
|
rex::ui::Window::AutoFrameCapHz(rex::ui::Window::CachedDisplayRefreshHz());
|
||||||
row.options.push_back(
|
row.options.push_back(
|
||||||
hz >= 30.0f
|
auto_cap > 0.0f
|
||||||
? "Auto (" + std::to_string(int(hz) - 4) + " FPS)"
|
? "Auto (" + std::to_string(int(auto_cap)) + " FPS)"
|
||||||
: std::string("Auto"));
|
: std::string("Auto"));
|
||||||
}
|
}
|
||||||
for (size_t i = 1; i < kFrameCapLabels.size(); ++i) {
|
for (size_t i = 1; i < kFrameCapLabels.size(); ++i) {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <cmath>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
#include <rex/assert.h>
|
#include <rex/assert.h>
|
||||||
|
|
@ -78,6 +79,17 @@ void Window::UpdateCachedDisplayRefresh() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Window::AutoFrameCapHz(float refresh_hz) {
|
||||||
|
if (refresh_hz < 30.0f) {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
// 4 FPS of margin or 5% of the refresh rate, whichever is larger (see the
|
||||||
|
// declaration): 4 FPS is 6.7% of headroom at 60 Hz but only 0.2 ms of
|
||||||
|
// present slack at 144 Hz, within routine thread-scheduling jitter.
|
||||||
|
const float margin = std::max(4.0f, refresh_hz * 0.05f);
|
||||||
|
return std::floor(refresh_hz - margin);
|
||||||
|
}
|
||||||
|
|
||||||
Window::Window(WindowedAppContext& app_context, const std::string_view title,
|
Window::Window(WindowedAppContext& app_context, const std::string_view title,
|
||||||
uint32_t desired_logical_width, uint32_t desired_logical_height)
|
uint32_t desired_logical_width, uint32_t desired_logical_height)
|
||||||
: app_context_(app_context),
|
: app_context_(app_context),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue