This is simpler in general, given that this function is no longer used
from user-space. In this particular case, the secondary purpose is to
allow easily adding arguments to the function.
This patch addresses an issue in Second Life and potentially other
multi-threaded applications which process WM_KEYDOWN in one thread
and then verify that the key is "still down" with GetAsyncKeyState
from another thread. Wine uses a per-thread key cache, resulting
in inconsistent views of key status. Caches are now invalidated
when an input event is injected by the driver or via SendInput.
Track ticks since draw start per window_surface, instead of per DC as is
currently the case. This change helps reduce visual glitches caused by
badly timed flushes when drawing to the same window_surface from
multiple DCs (e.g., for child windows).
This approach is a better fit for the current heuristic for forcing
flushing, which consults the shared window_surface bounds to decide
whether this is the start of a draw in order to reset the (currently per
DC) draw start time.
The problem in the current implementation occurs when a drawing to a DC
begins with an already damaged window_surface, e.g., due to draws from
other DCs targeting that window_surface. In such a case, the DC draw
start time is not reset and refers to the start of some previous draw
sequence using this DC, thus increasing the chances that the 50ms time
flush limit will be eventually exceeded in the middle of the current
draw sequence. In other words, the state of the (shared) window_surface
damage is not a reliable indicator of the beginning (or not) of a draw
to a DC.
An example, assuming DC1 and DC2 target the same window_surface:
DC1.start_ticks = 0
DC2.start_ticks = 0
FLUSH_PERIOD = 50
0 flush
1 draw to DC1 -> DC1.start_ticks = 1
... [no flush] ...
2 draw to DC2 -> DC2.start_ticks remains 0 since surface is damaged
...
50 flush
51 draw to DC1 -> DC1.start_ticks = 51
... [no flush] ...
52 draw to DC2 -> DC2.start_ticks remains 0 since surface is damaged,
current - DC2.start_ticks > FLUSH_PERIOD so we are
forced to flush in the middle of the drawing
sequence => potential glitch
Tracking the draw start per window_surface ameliorates the problem
because the beginning of a draw on a DC targeting an undamaged
window_surface resets the start time for all DCs targeting that
window_surface:
...
50 flush
51 draw to DC1 -> surface.draw_ticks = 51
... [no flush] ...
52 draw to DC2 -> surface.draw_ticks remains 51 since surface is damaged,
but current - surface.draw_ticks < FLUSH_PERIOD, so we
do not flush
Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>