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).
|
||||
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.
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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 "
|
||||
"refresh rate cannot be shown and only make steady motion judder.";
|
||||
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(
|
||||
hz >= 30.0f
|
||||
? "Auto (" + std::to_string(int(hz) - 4) + " FPS)"
|
||||
auto_cap > 0.0f
|
||||
? "Auto (" + std::to_string(int(auto_cap)) + " FPS)"
|
||||
: std::string("Auto"));
|
||||
}
|
||||
for (size_t i = 1; i < kFrameCapLabels.size(); ++i) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <cmath>
|
||||
#include <iterator>
|
||||
|
||||
#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,
|
||||
uint32_t desired_logical_width, uint32_t desired_logical_height)
|
||||
: app_context_(app_context),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue