On Wed Aug 30 13:43:16 2023 +0000, Alexandros Frantzis wrote:
As noted in the description there is the potential for bad interactions between the driver input event dispatching and the win32u window flushing mechanism. For an example of this just move the pointer around within the scrollbar in `notepad` (when using the `light` theme), which at least on my system cause artifacts. The root cause seems to be that the driver can queue enough (motion) messages to prevent the message loop from becoming idle (and thus flush the surfaces) for an extended period. If we reach the 50ms limit without having flushed, we are forced to flush in `dlls/win32u/dibdrv/dc.c:unlock_surface` at unfortunate points during rendering, leading to artifacts. For a more concrete description of what I understand to be happening using the scrollbar scenario (assume 3 Wayland motion events every 8ms, each scrollbar draw takes 20ms):
Wayland event thread UI thread -------------------- --------- 0: GetMessage... no messages, idle so flush_window_surface(TRUE), wait 0: Wayland: motion event 1 0: GetMessage -> WM_MOUSEMOVE 1 0: DrawScrollbar 8: Wayland: motion event 2 16: Wayland: motion event 3 20: GetMessage -> not idle, WM_MOUSEMOVE 2 20: DrawScrollbar 40: GetMessage -> not idle, WM_MOUSEMOVE 3 40: DrawScrollbar... 50: ...but we pass 50ms since last flush (at 0ms), so we flush before DrawScrollbar is done
Under X11, even though the motion event frequency is similar (again, let's say every 8ms), the X11 motion events are dispatched from the message loop thread one at a time, allowing the message loop to become idle, like so:
UI thread --------- 0: GetMessage... no messages, idle so flush_window_surface(TRUE), wait 0: X11: motion event 1 0: GetMessage -> WM_MOUSEMOVE 1 0: DrawScrollbar 20: GetMessage... no messages, idle so flush_window_surface(TRUE), wait 20: X11: motion event 2 20: GetMessage -> WM_MOUSEMOVE 2 20: DrawScrollbar 40: GetMessage... no messages, idle so flush_window_surface(TRUE), wait ...
I've toyed with some ideas in the Wayland driver, but I haven't found a solution that's effective. I would appreciate any thoughts from someone more experienced in this area of `win32u`. Do you think that some kind of change in the `win32u` flushing logic could be an acceptable way forward?
20ms to draw a scrollbar feels a bit much, doesn't it?