Repository navigation
Conversation
fb2ff77 to
558af9c
Compare
3f5aece to
208ec0c
Compare
|
@mkaspryk-synaptics Thanks for your comment, all your points are addressed and I also fixed a few more things I ran into. |
hrtimer_setup() replaced hrtimer_init() plus a separate .function assignment in 6.13. Add an EVDI_HAVE_HRTIMER_SETUP probe so the vblank timer setup can pick the right API at compile time.
The .enable_vblank and .disable_vblank hooks were guarded by EVDI_HAVE_CRTC_ATOMIC_STATE_ARG, which is false on 7.2 and later where the callbacks moved to struct drm_atomic_commit. On those kernels the hooks were dropped and vblank could never be enabled. Guard them with EVDI_HAVE_IOSYS_MAP or EVDI_HAVE_DMA_BUF_MAP (5.11+) instead, the same condition evdi_drm_drv.c uses for its driver level vblank hooks. The hooks still return 1 here so this change is behaviour neutral on its own.
evdi faked vblank by returning 1 from enable_vblank and never delivering timing to userspace, so compositors had no frame pacing. Drive drm_crtc_handle_vblank() from an hrtimer whose period comes from the mode timings (vtotal * htotal * 1e6 / clock, 60 Hz default). Start the timer in enable_vblank, cancel it in disable_vblank and retune the period on mode change. Use div_u64 for the period so the 64-bit divide links on 32-bit ARM, and READ_ONCE/WRITE_ONCE around vblank_period which is written on mode change and read from the timer callback. Detect hrtimer_setup() via the new probe and fall back to hrtimer_init() plus .function before 6.13. Cancel the timer in evdi_drm_device_release_cb too and guard evdi_crtc_destroy because drmm cleanup frees evdi before drm_mode_config_cleanup runs.
The painter used to hold the page-flip event until userspace grabbed pixels, then sent it immediately, so flips completed off any real vblank. Arm the event with drm_crtc_arm_vblank_event() so it fires on the next tick, falling back to an immediate send if drm_crtc_vblank_get() fails. Take event_lock with spin_lock_irq because the vblank hrtimer callback takes it in hard irq context. Drop the now unused painter vblank path.
Cover the period math (default 60 Hz, a 144 Hz mode and a clock of 0 keeping the previous period), that the timer arms and is scheduled within one period after drm_crtc_vblank_on and that it stops and the vblank count freezes after drm_crtc_vblank_off.
208ec0c to
17d579e
Compare
There was a problem hiding this comment.
Thank you for working on this.
I think that we need to sort out when to handle vblank when userspace client won't manage to grab pixels in time. This might happen on low performance machines which displays 4k content, or when the machine is busy.
Maybe it is enough to defer the vblank to next vblank_period.
On the other hand sometimes it is better to drop the frame when there is new one and show the new one earlier. Can you experiment with that?
We should test it how this works with Gnome/Mutter, Gnome/Xorg and weston.
There was a problem hiding this comment.
@IraSkyx
Please also add regression coverage for the late-grabpix case: when a newer frame arrives before an older vblank event is consumed, confirm the behavior matches the intended policy — either coalesce to the next vblank or drop the stale event in favor of the newest frame. This is the key correctness boundary for the hrtimer-based pacing change

Fixes #512, partially addresses #511.
enable_vblankreturns 1 sodrm_atomic_helper_wait_for_vblanksskips the CRTC on every commit. No frame pacing, tearing on compositors that rely on it.The painter-based event path (
evdi_painter_set_vblank) doesn't help either: when commits outpacegrabpix, the previous event gets flushed during the current atomic flush.This adds an hrtimer driving
drm_crtc_handle_vblankat the mode's refresh rate and switches todrm_crtc_arm_vblank_eventin the atomic flush, same pattern as vkms.UPDATE_READYis unchanged.Tested on Hyprland, 1080p@60Hz DisplayLink (Dell D6000), kernel 7.2. No more tearing, properly paced, clean hotplug and module unload.