summaryrefslogtreecommitdiff
path: root/src/core/perf_stats.cpp
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2017-02-20 16:31:59 -0800
committerGravatar Yuri Kunde Schlesner2017-02-26 17:22:04 -0800
commitfb1979d7e26c20fe2b8d2c3d3dc998e5e00f2f61 (patch)
tree690461954bff040727fa2cb3b34c9d71c003ea9c /src/core/perf_stats.cpp
parentCore: Make PerfStats internally locked (diff)
downloadyuzu-fb1979d7e26c20fe2b8d2c3d3dc998e5e00f2f61.tar.gz
yuzu-fb1979d7e26c20fe2b8d2c3d3dc998e5e00f2f61.tar.xz
yuzu-fb1979d7e26c20fe2b8d2c3d3dc998e5e00f2f61.zip
Core: Re-write frame limiter
Now based on std::chrono, and also works in terms of emulated time instead of frames, so we can in the future frame-limit even when the display is disabled, etc. The frame limiter can also be enabled along with v-sync now, which should be useful for those with displays running at more than 60 Hz.
Diffstat (limited to 'src/core/perf_stats.cpp')
-rw-r--r--src/core/perf_stats.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp
index 06bc788bd..eb59a1332 100644
--- a/src/core/perf_stats.cpp
+++ b/src/core/perf_stats.cpp
@@ -4,11 +4,16 @@
4 4
5#include <chrono> 5#include <chrono>
6#include <mutex> 6#include <mutex>
7#include <thread>
8#include "common/math_util.h"
7#include "core/hw/gpu.h" 9#include "core/hw/gpu.h"
8#include "core/perf_stats.h" 10#include "core/perf_stats.h"
11#include "core/settings.h"
9 12
13using namespace std::chrono_literals;
10using DoubleSecs = std::chrono::duration<double, std::chrono::seconds::period>; 14using DoubleSecs = std::chrono::duration<double, std::chrono::seconds::period>;
11using std::chrono::duration_cast; 15using std::chrono::duration_cast;
16using std::chrono::microseconds;
12 17
13namespace Core { 18namespace Core {
14 19
@@ -69,4 +74,32 @@ double PerfStats::GetLastFrameTimeScale() {
69 return duration_cast<DoubleSecs>(previous_frame_length).count() / FRAME_LENGTH; 74 return duration_cast<DoubleSecs>(previous_frame_length).count() / FRAME_LENGTH;
70} 75}
71 76
77void FrameLimiter::DoFrameLimiting(u64 current_system_time_us) {
78 // Max lag caused by slow frames. Can be adjusted to compensate for too many slow frames. Higher
79 // values increases time needed to limit frame rate after spikes.
80 constexpr microseconds MAX_LAG_TIME_US = 25ms;
81
82 if (!Settings::values.toggle_framelimit) {
83 return;
84 }
85
86 auto now = Clock::now();
87
88 frame_limiting_delta_err += microseconds(current_system_time_us - previous_system_time_us);
89 frame_limiting_delta_err -= duration_cast<microseconds>(now - previous_walltime);
90 frame_limiting_delta_err =
91 MathUtil::Clamp(frame_limiting_delta_err, -MAX_LAG_TIME_US, MAX_LAG_TIME_US);
92
93 if (frame_limiting_delta_err > microseconds::zero()) {
94 std::this_thread::sleep_for(frame_limiting_delta_err);
95
96 auto now_after_sleep = Clock::now();
97 frame_limiting_delta_err -= duration_cast<microseconds>(now_after_sleep - now);
98 now = now_after_sleep;
99 }
100
101 previous_system_time_us = current_system_time_us;
102 previous_walltime = now;
103}
104
72} // namespace Core 105} // namespace Core