display: pace the frame clock by the panel's EDID refresh rate
Both EDID moments the system has are now captured and carried to the compositor's frame clock: - EFI: the loader derives refresh from the preferred detailed timing (pixel clock / total pixels) while GOP is still alive — the only moment it is readable — and hands it through the boot handoff into the display0 node's DisplayInfo (new refresh_hz field, 0 = unknown). - GPU: the virtio-gpu driver derives the same figure from its own EDID read and carries it in the attach_scanout announce (request.y). updateFrameClock() re-derives the interval from the active backend's info at bring-up and again on every backend change — the boot framebuffer's clock dies with the GOP floor at upgrade, replaced by the GPU's rate. Unknown rate defaults to 60 Hz; the result is clamped to [30, 120] Hz so a mis-parsed EDID can neither starve nor flood the compositor. Rate only, never phase: without vblank, presents still free-run (docs/display-v2.md, 'Fenced is not vsync'). Observed in QEMU: OVMF exposes no EDID for the VGA adapter, so the GOP floor logs 'frame clock 62 Hz (default)' (real firmware does expose it); the virtio-gpu EDID advertises 75 Hz and the upgrade logs 'frame clock 76 Hz (panel EDID)'. The display kernel test asserts refresh_hz rides the seeded node; all 7 display QEMU cases pass.
This commit is contained in:
@@ -37,6 +37,11 @@ pub const Framebuffer = extern struct {
|
||||
height: u32, // visible rows (e.g. 1080)
|
||||
pitch: u32, // bytes from the start of one row to the start of the next
|
||||
format: PixelFormat,
|
||||
/// The panel's refresh rate in Hz, computed from its EDID preferred timing (pixel
|
||||
/// clock / total pixels per frame) while GOP was still alive — the one moment it is
|
||||
/// readable (docs/gop.md). 0 = unknown (no EDID). The display service paces its
|
||||
/// frame clock by it; without vblank this fixes the *rate*, never the *phase*.
|
||||
refresh_hz: u32 = 0,
|
||||
|
||||
/// Whether a usable framebuffer was handed over.
|
||||
pub fn present(self: Framebuffer) bool {
|
||||
|
||||
Reference in New Issue
Block a user