-
-
Notifications
You must be signed in to change notification settings - Fork 4
Tearing, stuttering, judder, hiccups
A multithreaded emulator has multiple sources of screen tearing and stuttering.
By multithreaded I mean an emulator that has at least 2 main threads: a machine emulation thread (CPU and I/O devices - VGA, disk interfaces, etc.) and a GUI thread (the main user interface). It can have other workers (e.g. for audio rendering) or sub-threads (video recording compression, multithreaded CPU and/or devices, ...), but for the sake of this discussion I'll consider only the main 2.
This kind of screen tearing is caused when the emulation and GUI threads are de-synchronized, the VGA device is emulated with a timed per-scanline rendering method, and the VGA image buffer is displayed directly by the GUI.
This kind of tearing can be fixed with an intermediate buffer that is updated by the emulation thread only after the VGA image is fully rendered. This will add some latency.
Another approach would be synchronizing the emulation and GUI threads and update the VGA image only at display end, when it's fully rendered.
Yet another "solution" would be using a per-frame VGA rendering algorithm, where the full image is rendered only at CRT "display end", but many DOS games and demos that depend on scanline effects would have graphical glitches. Currently IBMulator employs a per-scanline rendering method for every video mode below 480p.
This is a desynchronization between the GUI thread and the host video subsystem. It happens when the GUI updates the VGA video frame and your monitor is still displaying the previous one. This is the common case of tearing and it can affect every program, not just emulators.
Usually this is not a problem, at least for windowed programs, as the OS's compositor is v-synched and/or triple-buffered.
Some O.S. disable v-sync and/or triple-buffering when the program is put in full screen mode, so you can potentially suffer from screen tearing, unless you explicitly enable v-sync in the program's options.
A possible definitive and optimal solution would be using an Adaptive Sync monitor. Unfortunately I can't verify nor implement this solution in IBMulator as I don't possess an Adaptive Sync monitor at this time.
This happens when some VGA frames are repeated at regular intervals (frame doubling), eg:
1 2 3 3 4 5 6 6 7 8 9 9 ...
or are skipped, again at regular intervals (frame dropping):
1 2 x 4 5 x 7 8 x 10 11 ...
It is caused by your monitor refresh rate not being exactly the same as the emulated VGA refresh rate (faster in the former example, slower in the latter), which is usually the case (please note the examples are exaggerated.)
It can be mitigated by a buffered approach with some kind of frame interpolation, which is a technique used by some video players. Unfortunately this method is difficult to use on real-time interactive applications like emulators as it would introduce a substantial amount of lag.
The only real solution would be an Adaptive Sync monitor. Unfortunately I don't have such a monitor so I can't implement this solution in IBMulator.
Video stuttering is when some frame of animation are missing at irregular intervals. For example:
1 2 3 x x x 7 8 x x 11 12 x 14 x 16 ...
x = frame that is rendered by the VGA thread but not presented by the GUI
Assuming the emulator is well programmed, stuttering is usually caused by the GUI thread not being fast enough, maybe because your PC's GPU cannot keep up with some shader.
It can also happen when the emulated CPU cannot keep up with the emulated DOS program, in which case the solution could be increasing the emulated CPU's frequency (beware of emulation stuttering though).
Emulation stuttering is when the Machine emulation thread is not executed fast enough by your CPU.
It manifests itself with:
- unevenly repeated frames of animation, for example:
1 2 3 4 4 5 6 6 7 8 9 9 9 ...
- audio crackling
You can solve this problem lowering the emulated CPU frequency and/or upgrading your PC.
Sometimes you notice some hiccups in the animation at seemingly random intervals, maybe just a repeated frame, that is not caused by any of the reasons already explained.
Random unevenness in animation could be caused by your OS, which interrupts the execution of the emulator to run some other program that has equal or greater priority. This is especially apparent when your PC is under load.
This phenomenon is completely unavoidable on common PCs and operating systems. You are at the mercy of the kernel's scheduler.
All the above conditions can happen at the same time, in which case you have a total mess.
In IBMulator various techniques are used to counter tearing, depending on the value of the [gui]:framecap
ini setting:
-
vga
: VSync is disabled, emulation and GUI threads sync is enabled, VGA buffering is disabled -
vsync
: VSync is enabled, threads sync is disabled, VGA buffering is enabled -
no
: VSync is disabled, threads sync is disabled, VGA buffering is enabled