VBLANK HANDLING(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ¦‹ vblank handling πŸ’…

okay bestie, so this is the whole vibe of vblank handling, from the Kernel API Manual, and honestly it's giving main character energy for your display pipeline. let's get into it ✨

🌸 the basics, no cap πŸŽ€

From the computer's perspective, every single time the monitor shows a new frame, the scanout engine has "scanned out" the display image from top to bottom, one row of pixels at a time. The current row of pixels? That's the current scanline. periodt.

And on top of the display's visible area, there's usually a couple of extra scanlines that aren't actually displayed on screen. These extra scanlines don't contain image data and are occasionally used for features like audio and infoframes. The region made up of these scanlines is the vertical blanking region, aka vblank for short. iykyk 🫢

For historical reference (yes, we're doing lore πŸ‘‘): the vertical blanking period was designed to give the electron gun (on CRTs) enough time to move back to the top of the screen to start scanning out the next frame. Similar deal for horizontal blanking periods β€” they were designed to give the electron gun enough time to move back to the other side of the screen to start scanning the next scanline. iconic little race condition avoidance, honestly.


πŸŽ€ the diagram (art, literally) πŸ–ΌοΈ

          physical β†’   ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
          top of      |                                        |
          display     |                                        |
                      |               New frame                |
                      |                                        |
                      |↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓|
                      |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| ← Scanline,
                      |↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓|   updates the
                      |                                        |   frame as it
                      |                                        |   travels down
                      |                                        |   ("scan out")
                      |               Old frame                |
                      |                                        |
                      |                                        |
                      |                                        |
                      |                                        |   physical
                      |                                        |   bottom of
          vertical    |⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽| ← display
          blanking    ┆xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx┆
          region   β†’  ┆xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx┆
                      ┆xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx┆
          start of β†’   ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
          new frame

✨ so "Physical top of display" is the reference point for the high-precision/corrected timestamp. that's the anchor, bestie, remember her.


πŸ”₯ why anyone cares (the programming bit) πŸ’€

On a lot of display hardware, programming needs to take effect during the vertical blanking period so that settings like gamma, the image buffer to be scanned out, etc. can safely be changed without showing any visual artifacts on the screen. literally the whole point.

And on some unforgiving hardware, some of this programming has to both start and end in the same vblank. 😭 To help with the timing of the hardware programming, an interrupt is usually available to notify the driver when it can start updating registers. That interrupt is called the vblank interrupt in this context. slay.

The vblank interrupt may be fired at different points depending on the hardware. Some hardware implementations will fire the interrupt when the new frame start, other implementations will fire the interrupt at different points in time. so, like, vibe varies β€” check your hardware 🧚


πŸ‘‘ vblank in graphics rendering 🌈

Vertical blanking plays a major role in graphics rendering. To achieve tear-free display, users must synchronize page flips and/or rendering to vertical blanking. The DRM API offers ioctls to perform page flips synchronized to vertical blanking and wait for vertical blanking. no tears, only glow ✨

The DRM core handles most of the vertical blanking management logic, and honestly the list of chores is a lot:

  • filtering out spurious interrupts
  • keeping race-free blanking counters
  • coping with counter wrap-around and resets
  • keeping use counts

It relies on the driver to generate vertical blanking interrupts and optionally provide a hardware vertical blanking counter.


πŸ’– driver duties (what you actually have to do) 🫢

Drivers must initialize the vertical blanking handling core with a call to drm_vblank_init. Minimally, a driver needs to implement drm_crtc_funcs.enable_vblank and drm_crtc_funcs.disable_vblank, plus call drm_crtc_handle_vblank in its vblank interrupt handler for working vblank support. that's the bare minimum bestie, don't skip it πŸ™ˆ

Vertical blanking interrupts can be enabled by the DRM core or by drivers themselves (for instance to handle page flipping operations). The DRM core maintains a vertical blanking use count to ensure that the interrupts are not disabled while a user still needs them. To increment the use count, drivers call drm_crtc_vblank_get and release the vblank reference again with drm_crtc_vblank_put. In between these two calls vblank interrupts are guaranteed to be enabled. πŸŽ€

⚠️ heads up: on many hardware, disabling the vblank interrupt cannot be done in a race-free manner β€” see drm_vblank_crtc_config.disable_immediate and drm_driver.max_vblank_count. In that case the vblank core only disables the vblanks after a timer has expired, which can be configured through the vblankoffdelay module parameter. so like... it's a whole thing πŸ’€

🧚 no interrupts? timers to the rescue ⭐

Drivers for hardware without support for vertical-blanking interrupts can use DRM vblank timers to send vblank events at the rate of the current display mode's refresh. While not synchronized to the hardware's vertical-blanking regions, the timer helps DRM clients and compositors to adapt their update cycle to the display output. Drivers should set up vblanking as usual, but call drm_crtc_vblank_start_timer and drm_crtc_vblank_cancel_timer as part of their atomic mode setting. See also DRM vblank helpers for more information. πŸ¦‹

And for the drivers with no vertical-blanking interrupts nor timers: they must not call drm_vblank_init. For these drivers, atomic helpers will automatically generate fake vblank events as part of the display update. This functionality also can be controlled by the driver by enabling and disabling struct drm_crtc_state.no_vblank. fake it till you make it, honestly πŸ’…


πŸ¦‹ SEE ALSO πŸ¦‹


and that's the page!! πŸŽ€ this one lives in ./drivers/gpu/drm, dated October 2026, and it's vblank handling(9) out of the Kernel API Manual. go forth and sync your page flips bestie, ily πŸ’œβœ¨

πŸ“¦ where this page comes from