1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-22 12:33:29 +00:00

Attempts to improve vsync deadline estimation.

Also increases probability of bad estimation being discarded.
This commit is contained in:
Thomas Harte 2020-07-27 21:08:00 -04:00
parent db8e1b0edf
commit 3db4a8c312
2 changed files with 11 additions and 7 deletions

View File

@ -63,6 +63,13 @@ class VSyncPredictor {
frame_duration_ = Nanos(1'000'000'000.0f / rate); frame_duration_ = Nanos(1'000'000'000.0f / rate);
} }
/*!
@returns The time this class currently believes a whole frame occupies.
*/
Time::Nanos frame_duration() {
return frame_duration_;
}
/*! /*!
Adds a record of how much jitter was experienced in scheduling; these values will be Adds a record of how much jitter was experienced in scheduling; these values will be
factored into the @c suggested_draw_time if supplied. factored into the @c suggested_draw_time if supplied.
@ -87,15 +94,13 @@ class VSyncPredictor {
(if those figures are being supplied). (if those figures are being supplied).
*/ */
Nanos suggested_draw_time() { Nanos suggested_draw_time() {
const auto mean = redraw_period_.mean() - timer_jitter_.mean() - vsync_jitter_.mean(); const auto mean = redraw_period_.mean() + timer_jitter_.mean() + vsync_jitter_.mean();
const auto variance = redraw_period_.variance() + timer_jitter_.variance() + vsync_jitter_.variance(); const auto variance = redraw_period_.variance() + timer_jitter_.variance() + vsync_jitter_.variance();
// Permit three standard deviations from the mean, to cover 99.9% of cases. // Permit three standard deviations from the mean, to cover 99.9% of cases.
const auto period = mean - Nanos(3.0f * sqrt(float(variance))); const auto period = mean + Nanos(3.0f * sqrt(float(variance)));
assert(abs(period) < 10'000'000'000); return last_vsync_ + frame_duration_ - period;
return last_vsync_ + period;
} }
private: private:
@ -109,7 +114,6 @@ class VSyncPredictor {
} }
void post(Time::Nanos value) { void post(Time::Nanos value) {
assert(abs(value) < 10'000'000'000); // 10 seconds is a very liberal maximum.
sum_ -= history_[write_pointer_]; sum_ -= history_[write_pointer_];
sum_ += value; sum_ += value;
history_[write_pointer_] = value; history_[write_pointer_] = value;

View File

@ -86,7 +86,7 @@ void ScanTargetWidget::vsync() {
const auto time_now = Time::nanos_now(); const auto time_now = Time::nanos_now();
requestedRedrawTime = vsyncPredictor.suggested_draw_time(); requestedRedrawTime = vsyncPredictor.suggested_draw_time();
const auto delay_time = (requestedRedrawTime - time_now) / 1'000'000; const auto delay_time = (requestedRedrawTime - time_now) / 1'000'000;
if(delay_time > 0) { if(delay_time > 0 && delay_time < vsyncPredictor.frame_duration()) {
QTimer::singleShot(delay_time, this, SLOT(repaint())); QTimer::singleShot(delay_time, this, SLOT(repaint()));
} else { } else {
requestedRedrawTime = 0; requestedRedrawTime = 0;