Merge pull request #51495 from lawnjelly/fix_delta_overflow
Delta smoothing - fix overflow for long frames
This commit is contained in:
commit
35096325b8
|
@ -43,7 +43,7 @@ void MainFrameTime::clamp_idle(float min_idle_step, float max_idle_step) {
|
|||
|
||||
/////////////////////////////////
|
||||
|
||||
void MainTimerSync::DeltaSmoother::update_refresh_rate_estimator(int p_delta) {
|
||||
void MainTimerSync::DeltaSmoother::update_refresh_rate_estimator(int64_t p_delta) {
|
||||
// the calling code should prevent 0 or negative values of delta
|
||||
// (preventing divide by zero)
|
||||
|
||||
|
@ -195,7 +195,7 @@ void MainTimerSync::DeltaSmoother::update_refresh_rate_estimator(int p_delta) {
|
|||
}
|
||||
}
|
||||
|
||||
bool MainTimerSync::DeltaSmoother::fps_allows_smoothing(int p_delta) {
|
||||
bool MainTimerSync::DeltaSmoother::fps_allows_smoothing(int64_t p_delta) {
|
||||
_measurement_time += p_delta;
|
||||
_measurement_frame_count++;
|
||||
|
||||
|
@ -209,8 +209,8 @@ bool MainTimerSync::DeltaSmoother::fps_allows_smoothing(int p_delta) {
|
|||
|
||||
// estimate fps
|
||||
if (time_passed) {
|
||||
float fps = 1000000.0f / time_passed;
|
||||
float ratio = fps / (float)_estimated_fps;
|
||||
double fps = 1000000.0 / time_passed;
|
||||
double ratio = fps / (double)_estimated_fps;
|
||||
|
||||
//print_line("ratio : " + String(Variant(ratio)));
|
||||
|
||||
|
@ -230,7 +230,7 @@ bool MainTimerSync::DeltaSmoother::fps_allows_smoothing(int p_delta) {
|
|||
return _measurement_allows_smoothing;
|
||||
}
|
||||
|
||||
int MainTimerSync::DeltaSmoother::smooth_delta(int p_delta) {
|
||||
int64_t MainTimerSync::DeltaSmoother::smooth_delta(int64_t p_delta) {
|
||||
// Conditions to disable smoothing.
|
||||
// Note that vsync is a request, it cannot be relied on, the OS may override this.
|
||||
// If the OS turns vsync on without vsync in the app, smoothing will not be enabled.
|
||||
|
@ -240,6 +240,12 @@ int MainTimerSync::DeltaSmoother::smooth_delta(int p_delta) {
|
|||
return p_delta;
|
||||
}
|
||||
|
||||
// Very important, ignore long deltas and pass them back unmodified.
|
||||
// This is to deal with resuming after suspend for long periods.
|
||||
if (p_delta > 1000000) {
|
||||
return p_delta;
|
||||
}
|
||||
|
||||
// keep a running guesstimate of the FPS, and turn off smoothing if
|
||||
// conditions not close to the estimated FPS
|
||||
if (!fps_allows_smoothing(p_delta)) {
|
||||
|
@ -266,7 +272,7 @@ int MainTimerSync::DeltaSmoother::smooth_delta(int p_delta) {
|
|||
_leftover_time += p_delta;
|
||||
|
||||
// how many vsyncs units can we fit?
|
||||
int units = _leftover_time / _vsync_delta;
|
||||
int64_t units = _leftover_time / _vsync_delta;
|
||||
|
||||
// a delta must include minimum 1 vsync
|
||||
// (if it is less than that, it is either random error or we are no longer running at the vsync rate,
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue