Frame-based motion event compression



One of the concepts of the paint-clock work is that it also should be
used for event delivery and compression. The idea is that instead of
continually delivering events and possibly never getting to updating,
we batch up events and deliver them right before doing the other work
of the frame. This allows to "look ahead" and compress consecutive
motion events.

This is the approach that was taken for Clutter. However, doing it
for GTK+ would create serious compatibility because it's very common
in current GTK+ programs to add idle handlers that have a more
urgent priority than GDK_PRIORITY_RESIZE,  and expect those handlers
to actually be run before resizing. I found about 70 idles being added
at a priority above RESIZE in the GNOME code checked out on my laptop.
It's hard to say how many of these actually are triggered from event
handlers, but some of them certainly are.

The alternate approach I took was instead to make the paint clock
install two separate idle handlers, so we have the following sources
from high to low in priority:

 G_PRIORITY_DEFAULT     - GDK Event Handling - Events are proccessed, motion events
                                               are not flushed to GTK+ until some
                                               other events comes in. Consecutive
                                               motion events are deleted.

 G_PRIORITY_DEFAULT + 1 - ::flush-events       Pending motion event is flushed
                                               Event delivery is paused

 <added idle handlers can run>

 GDK_PRIORITY_REDRAW      ::before-paint
                          ::update             Animations are updated
                          ::layout             size request and size allocate
                          ::paint              Everything is redrawn
                          ::after-paint
                          ::resume-events      Event delivery is resumed

Pausing the event delivery is necessary because if you don't pause
event delivery, then if the motion event delivery takes significant
amount of time and more motion events arrive, you will return
immediately to the event source at G_PRIORITY_DEFAULT and never get
to drawing.

The current implementation of this in my branch is fairly simplistic
in how it does motion event compression - it only ever compresses motions
if they are completely consecutive in the event queue - any other events,
even if they are completely unrelated to the mouse will flush out motion
events and  prevent compression. More sophisticated approaches are possible
but may not be necessary.

We've already done a lot of work at suppressing mouse lag in the GTK+
core, so there wasn't much noticeable affect for things like dragging
scrollbars, but the patch does make a huge difference for an artificial
test case I wrote that calls g_usleep() in its motion event handler.

- Owen




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]