emilk / emilk/egui

Frametime inconsistency in reactive mode

Open
#8,141 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Rust
Stars
30.6k
Forks
2.1k
Avg merge
1d 9h
Merged PRs (30d)
72

Description

**Describe the bug**

By default (reactive mode + vsync) there appears to be some frametime inconsistency when rendering is resumed after inactivity. Specifically, there's one very short frame immediately following the pause, possibly run as fast as possible. Here's some measurements, in milliseconds:

```
[frame 21] elapsed: 8.278501
[frame 22] elapsed: 8.316401
[frame 23] elapsed: 8.2283
[frame 24] elapsed: 3728.6328 <--- user input after inactivity
[frame 25] elapsed: 1.0372 <--- short frame
[frame 26] elapsed: 8.1277
[frame 27] elapsed: 8.347
[frame 28] elapsed: 8.330601
[frame 29] elapsed: 8.1791
[frame 30] elapsed: 8.2477
[frame 31] elapsed: 1424.3766 <--- user input after inactivity
[frame 32] elapsed: 1.1936 <--- short frame
[frame 33] elapsed: 8.1066
[frame 34] elapsed: 8.365299
[frame 35] elapsed: 8.516299
[frame 36] elapsed: 7.9996996
[frame 37] elapsed: 8.2352
[frame 38] elapsed: 8.4309
[frame 39] elapsed: 8.148
[frame 40] elapsed: 8.438601
[frame 41] elapsed: 8.127399
[frame 42] elapsed: 8.4358
[frame 43] elapsed: 8.132199
[frame 44] elapsed: 8.3171
[frame 45] elapsed: 3144.8467 <--- user input after inactivity
[frame 46] elapsed: 1.1059 <--- short frame
[frame 47] elapsed: 8.1105
[frame 48] elapsed: 8.3281
[frame 49] elapsed: 8.3275
[frame 50] elapsed: 8.4655
[frame 51] elapsed: 7.9945
[frame 52] elapsed: 21.1372 <--- ??
[frame 53] elapsed: 0.7083 <--- short frame
[frame 54] elapsed: 9.1266
[frame 55] elapsed: 8.3132
[frame 56] elapsed: 3926.7778 <--- user input after inactivity
[frame 57] elapsed: 1.082 <--- short frame
[frame 58] elapsed: 8.0842
[frame 59] elapsed: 8.3047
```
Not sure if it's egui doing it, but there appears to be some level of compensation for frames that deviate from the vsync target. This has a place, but render pauses caused by reactive mode shoudn't be treated the same as actual deviations, especially not when they're beyond compensation: it's one thing to compensate a millisecond of stutter, but it's not possible to gracefully recover from a 3 seconds pause.

This is not ideal because depending on what's happening and how frames are presented it could result in what's essentially a doubled frame/stutter as far as motion perception is concerned. This happens because while the cpu might sample animations based on the measured time delta, the end result has to conform to the screen's constant rate.

**To Reproduce**

Start a timer with `Instant::now()` and each frame measure the total elapsed time and subtract the previous value from it. It may not be nanosecond-accurate but should be good enough to detect the phenomenon described.

**Expected behavior**
Perhaps optionally, I'd like all frames in reactive mode to be evenly spaced at computation time as soon as user input is received. I'd want measurements to look something like this:
```
[frame 43] elapsed: 8.33
[frame 44] elapsed: 8.33
[frame 45] elapsed: 5000.00 <--- 5s inactivity
[frame 46] elapsed: 8.33 <--- evenly spaced from the previous frame, no compensation
[frame 47] elapsed: 8.33
[frame 48] elapsed: 8.67 < --- longer than expected
[frame 49] elapsed: 8.00 < --- small compensations are fine in such cases
[frame 50] elapsed: 8.33
```
Additionally, If not already happening, some extra latency of up to a frame should ideally be added on input resume to align the cpu rendering window to that of the previous frames.

**Desktop (please complete the following information):**
- OS: Windows 10
- Version: 0.34.1

Contributor guide

Open the contributing guide

Research direction

No file or test is named. Start by reproducing the issue in reactive mode with vsync, measuring consecutive frame intervals using Instant::now(), then trace the reactive-mode frame scheduling and timing path. Done means resumed frames no longer receive large-pause compensation, while small timing deviations can still be compensated.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.