Skip to content
  • Mario Kleiner's avatar
    compositor-drm: Allow instant start of repaint loop. (v4) · f507ec35
    Mario Kleiner authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    
    drm_output_start_repaint_loop() incurred a delay of
    one refresh cycle by using a no-op page-flip to get
    an accurate vblank timestamp as reference. This causes
    unwanted lag whenever Weston exited its repaint loop, e.g.,
    whenever an application wants to repaint with less than
    full video refresh rate but still minimum lag.
    
    Try to use the drmWaitVblank ioctl to get a proper
    timestamp instantaneously without lag. If that does
    not work, fall back to the old method of idle page-flip.
    
    This optimization will work on any drm/kms driver
    which supports high precision vblank timestamping.
    As of Linux 4.0 these would be intel, radeon and
    nouveau on all their supported gpu's.
    
    On kms drivers without instant high precision timestamping
    support, the kernel is supposed to return a timestamp
    of zero when calling drmWaitVblank() to query the current
    vblank count and time iff vblank irqs are currently
    disabled, because the only way to get a valid timestamp
    on such kms drivers is to enable vblank interrupts and
    then wait a bit for the next vblank irq to take a new valid
    timestamp. The caller is supposed to poll until at next
    vblank irq it gets a valid non-zero timestamp if it needs
    a timestamp.
    
    This zero-timestamp signalling works up to Linux 3.17, but
    got broken due to a regression in Linux 3.18 and later. On
    Linux 3.18+ with kms drivers that don't have high precision
    timestamping, the kernel erroneously returns a stale timestamp
    from an earlier vblank, ie. the vblank count and timestamp are
    mismatched. A patch is under way to fix this, but to deal with
    broken kernels, we also check non-zero timestamps if they are
    more than one refresh duration in the past, as this indicates
    a stale/invalid timestamp, so we need to take the page-flip
    fallback for restarting the repaint loop.
    
    v2: Implement review suggestions by Pekka Paalanen, especially
        extend the commit message to describe when and why the
        instant restart won't work due to missing Linux kernel
        functionality or a Linux kernel regression.
    
    Signed-off-by: default avatarMario Kleiner <mario.kleiner.de@gmail.com>
    Reviewed-by: default avatarDaniel Stone <daniels@collabora.com>
    
    v3: Fix timespec_to_nsec() which was computing picoseconds,
        use the new timespec-util.h helpers.
    
    v4: Rebased to master, split long lines.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.co.uk>
    f507ec35