Multi-Buffering and vertical synchronization
Computer screens usually have a fixed refresh rate. For instance if the display device has a (vertical) refresh rate of 60Hz, it means that 60 times per second, the display device:
- copies the contents of the framebuffer on the screen: scan-out period
- waits for some time until the next scan-out: vertical blanking interval (v-blank interval)
If we modify the contents of the framebuffer that is displayed on the screen during the scan-out period, some artifacts may appear on the screen. To avoid this, we use vertical synchronization (v-sync or vsync): we only modify what is displayed during the vertical blanking interval.
If we use a single framebuffer, modifying its contents only during the vertical blanking interval may be difficult in practice as it imposes hard deadlines to complete the modifications.
Instead, we can use several framebuffers:
- the front buffer that is currently used for display and that is not modified
- the back buffer(s) that can be modified
When a framebuffer is ready to be displayed, it becomes the "front buffer" and the current front buffer becomes a "back buffer". The action of switching framebuffers is called page flipping.
The page flipping must occur during the v-blank interval, otherwise screen tearing may appear: some part of the displayed image is taken from the first buffer and some other part from the second one.
If we want to start rendering a new frame without waiting for the page flipping to complete, we can use more than one back buffer (e.g., triple buffering).
Rendering frames at the appropriate rate for the display may be difficult in some cases:
- the frame is complex and the time to render it is longer than a vsync period
- the frame rate is imposed by the source (e.g., a video encoded at 24 FPS) and is not compatible with the display's refresh rate
Adaptive vertical synchronization
If the computer can't generate frames fast enough for some refresh rates (e.g., in a game), it may be better to temporarily disable vertical synchronization to reduce the latency (hence avoiding stuttering) at the cost of some visual artefacts. This is a trade-off between image quality and sufficiently fast frame generation speed as you can't have both.
This is what NVIDIA names adaptive vsync.
There are several techniques to try to deal with incompatible frame rates, such as:
- if a frame is displayed during several periods, take this duration into account when rendering animated objects
- add motion blur to animated objects
- use interlaced frames
Further reading :
- Motion interpolation
The kernel can send events to user-space to signal the beginning of v-blank periods and to signal the completion of page flips.