forked from eden-emu/eden
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.
This commit is contained in:
parent
b285c2a4ed
commit
fb1979d7e2
5 changed files with 53 additions and 42 deletions
|
@ -4,11 +4,16 @@
|
|||
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include "common/math_util.h"
|
||||
#include "core/hw/gpu.h"
|
||||
#include "core/perf_stats.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
using DoubleSecs = std::chrono::duration<double, std::chrono::seconds::period>;
|
||||
using std::chrono::duration_cast;
|
||||
using std::chrono::microseconds;
|
||||
|
||||
namespace Core {
|
||||
|
||||
|
@ -69,4 +74,32 @@ double PerfStats::GetLastFrameTimeScale() {
|
|||
return duration_cast<DoubleSecs>(previous_frame_length).count() / FRAME_LENGTH;
|
||||
}
|
||||
|
||||
void FrameLimiter::DoFrameLimiting(u64 current_system_time_us) {
|
||||
// Max lag caused by slow frames. Can be adjusted to compensate for too many slow frames. Higher
|
||||
// values increases time needed to limit frame rate after spikes.
|
||||
constexpr microseconds MAX_LAG_TIME_US = 25ms;
|
||||
|
||||
if (!Settings::values.toggle_framelimit) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto now = Clock::now();
|
||||
|
||||
frame_limiting_delta_err += microseconds(current_system_time_us - previous_system_time_us);
|
||||
frame_limiting_delta_err -= duration_cast<microseconds>(now - previous_walltime);
|
||||
frame_limiting_delta_err =
|
||||
MathUtil::Clamp(frame_limiting_delta_err, -MAX_LAG_TIME_US, MAX_LAG_TIME_US);
|
||||
|
||||
if (frame_limiting_delta_err > microseconds::zero()) {
|
||||
std::this_thread::sleep_for(frame_limiting_delta_err);
|
||||
|
||||
auto now_after_sleep = Clock::now();
|
||||
frame_limiting_delta_err -= duration_cast<microseconds>(now_after_sleep - now);
|
||||
now = now_after_sleep;
|
||||
}
|
||||
|
||||
previous_system_time_us = current_system_time_us;
|
||||
previous_walltime = now;
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue