1
0
mirror of https://github.com/godotengine/godot.git synced 2026-01-06 19:41:11 +00:00

Delta smoothing - fix overflow for long frames

Extremely long frames caused by suspending and resuming the machine could result in an overflow in the delta smoothing because it uses 32 bit math on delta values measured in nanoseconds.

This PR puts a cap of a second as the maximum frame delta that will be processed by the smoothing, otherwise it returns the frame delta 64 bit value unaltered. It also converts internal math to explicitly use 64 bit integers.
This commit is contained in:
lawnjelly
2021-08-11 08:03:45 +01:00
parent 03c41fa34c
commit 3025b6d299
2 changed files with 23 additions and 17 deletions

View File

@@ -48,11 +48,11 @@ class MainTimerSync {
class DeltaSmoother {
public:
// pass the recorded delta, returns a smoothed delta
int smooth_delta(int p_delta);
int64_t smooth_delta(int64_t p_delta);
private:
void update_refresh_rate_estimator(int p_delta);
bool fps_allows_smoothing(int p_delta);
void update_refresh_rate_estimator(int64_t p_delta);
bool fps_allows_smoothing(int64_t p_delta);
// estimated vsync delta (monitor refresh rate)
int64_t _vsync_delta = 16666;
@@ -75,19 +75,19 @@ class MainTimerSync {
// we can estimate the fps by growing it on condition
// that a large proportion of frames are higher than the current estimate.
int _estimated_fps = 0;
int _hits_at_estimated = 0;
int _hits_above_estimated = 0;
int _hits_below_estimated = 0;
int _hits_one_above_estimated = 0;
int _hits_one_below_estimated = 0;
int32_t _estimated_fps = 0;
int32_t _hits_at_estimated = 0;
int32_t _hits_above_estimated = 0;
int32_t _hits_below_estimated = 0;
int32_t _hits_one_above_estimated = 0;
int32_t _hits_one_below_estimated = 0;
bool _estimate_complete = false;
bool _estimate_locked = false;
// data for averaging the delta over a second or so
// to prevent spurious values
int _estimator_total_delta = 0;
int _estimator_delta_readings = 0;
int64_t _estimator_total_delta = 0;
int32_t _estimator_delta_readings = 0;
void made_new_estimate() {
_hits_above_estimated = 0;