[Mono-winforms-list] Scrolling performance isues

Chris Toshok toshok at gmail.com
Fri Aug 1 16:54:26 EDT 2008

On Fri, Jul 25, 2008 at 11:34 AM, Ivan N. Zlatev <contact at i-nz.net> wrote:

> Carlos Alberto Cortez wrote:
> > Hey,
> >
> > The new code that detects not visibles areas of the window to scroll
> > (obscured by other mwf windows or x11 top level ones), although working
> > fine, is somewhat slow, as some people have noticed.
> >
> > After some research, I found that getting all the child windows for the
> > root window (using XQueryTree on RootWindow, this is, top level windows)
> > is the hot spot, and was causing the slow down.
> >
> > And after some more research in other graphics tool kits, found that:
> >
> > * Most of them make use of GraphicsExpose event, handling it by directly
> > generating expose events or invalidating the area pointed by
> > GraphicsExpose (Gtk+ as far as I know, and also Ivan told me other
> > frameworks do that).
> >
> Yes, this is because GraphicsExpose is designed exactly for that
> purpose. It is fired when a destination area can't be copied (XCopyArea)
> to because the source area is obscured. I still fail to see why we need
> special obscured-areas-checking logic when we can just handle that message.

You answer your question below - the reason why we couldn't use
GraphicsExpose is precisely because of the timing issue.  Calculating the
exact region to expose is just one possible solution (which turns out to
likely be the wrong one).

> I do understand that if we do indeed handle the GraphicsExpose message
> we stand the problem that it might get delayed (X11 message roundtrip
> time) until after we perform the next ScrollWindow/XCopyArea, so because
> the destination area (for the previous ScrollWindow call) won't be
> repainted yet we will copy that garbage from it to the next offset.
> However we currently have an explicit AddExpose just after the
> XCopyArea, so we are working around this problem by forcing a repaint on
> the queue, so that we are guaranteed to be repainted prior to the next
> ScrollWindow. And this just-works (tm) :-)
> If we want to handle it "properly" we can either"
> 1) Flush the paint queue prior to XCopyArea somehow
> ... or ...
> 2) "Block" the message queue until we get the last GraphicsExpose for
> the window, invalidate and then "unblock" the message queue.
> ... or ...
> 3) Something better
> > And also, regarding our code:
> >
> > * When using composite (Xgl or similar) it's not necessary to do this
> > detection, since the window manager (*it seems*) is doing something that
> > somehow already knows which areas need to get an expose event (in other
> > words: only mwf overlapping detection is needed, not for x top level
> > windows).
> > * The new code, at least in my laptop, without using composite, seems to
> > work fine (no performance lost), and don't know if it's because
> > XQueryTree on RootTree returns a minor number of windows (61 with no
> > composite, instead of 89 with composite, using 5 terminals and a gtk+
> > application, for example).
> >
> This I think is very implementation/environment/window manager/toolkit
> specific. E.g some toolkits/window managers might keep menu windows as
> hidden, but still mapped toplevels. I think this was referred to as one
> of the reason for the huge number of toplevels in some email I saw on a
> mailing list long time ago. Because of the variety of setups out there
> (window managers, toolkits, etc, etc) we can't really know with how many
> toplevels we are going to deal.
> To give you an example of the problem - on my GNOME + Metacity desktop
> with a standard set of programs running (Firefox, terminal, pidgin,
> nautilus, thunderbird, etc) XQueryTree returns 228 toplevels.
> > So, it seems that we should actually handle GraphicsExpose (which all it
> > involves) *or maybe* try to detect if we are using composite - if we
> > are, simply don't use this new code, but just do simple calculations,
> > and if we are not using it, do the detection, since it won't harm the
> > performance.
> >
> My personal position on the matter is that short-term (as in for Mono
> 2.0) we just handle GraphicsExpose instead of the new code and keep the
> AddExpose after XCopyArea to workaround the timing issue. Long-term we
> can look into adding a proper handling for the delays of GraphicsExpose
> if it's feasible.

This has me a little confused - adding handling for GraphicsExpose isn't
going to help anything if it's not done properly.  What I mean is, adding
the handling for GraphicsExpose (essentially adding the case statement and
doing an AddExpose) won't give us anything more than what we currently have,
since we can't guarantee that any of those events will have been received.
It's a trivial change, and might lessen the problem somewhat, but it won't
fix it.

I'm also not sure flushing the paint queue before doing the XCopyArea
(suggestion 1 above) will be enough either.  It's very easy to imagine a
scenario where you're scrolling and we do another ScrollWindow before all
the GraphicsExpose events have been received.  We really do need to block
things somehow.  And it'll be more than just blocking the message queue -
we'll need to actually stop the thread if there's a call to ScrollWindow (or
anything else that ends up copying) until the GraphicsExposes have been

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-winforms-list/attachments/20080801/a69eca21/attachment-0001.html 

More information about the Mono-winforms-list mailing list