XTranslateCoordinates() performance problem
- From: Owen Taylor <otaylor redhat com>
- To: gtk-devel-list gnome org
- Subject: XTranslateCoordinates() performance problem
- Date: 15 Nov 2001 23:33:04 -0500
Taking a look at where GTK+ was spending its time when opaque
resizing over a 10mb network, I noticed something interesting.
For ConfigureNotify events on toplevels, GTK+ does:
if (!xevent->xconfigure.send_event &&
!GDK_WINDOW_DESTROYED (window))
{
gint tx = 0;
gint ty = 0;
Window child_window = 0;
gdk_error_trap_push ();
if (XTranslateCoordinates (GDK_DRAWABLE_XDISPLAY (window),
GDK_DRAWABLE_XID (window),
_gdk_root_window,
0, 0,
&tx, &ty,
&child_window))
{
if (!gdk_error_trap_pop ())
{
event->configure.x = tx;
event->configure.y = ty;
}
}
else
gdk_error_trap_pop ();
}
else
{
event->configure.x = xevent->xconfigure.x;
event->configure.y = xevent->xconfigure.y;
}
The reason for this is so that event->configure.{x,y} can be
used to track the location of windows ... when you get a
configure event, it is either:
- A synthetic configure event because the window manager
moved the window manager frame and then (to conform
to the ICCCM) sends a synthetic configure.
- A real configure event because the window manager
resized or move/resized the client window.
In the former case, the coordinates are correct, in the
latter, they will be the coordinates within the frame
window.
Now, in response to a configure-notify where the size
changes (so, a real configure notify, and XTranslateCoordinates()
is called), GtkWindow queues an idle function to do the
resizing if there isn't already one done. Queueing an idle
like this only works if the work done for each event is
small enough so that you eventually go idle. Turns out,
that over 10mb XTranslateCoordinates() takes long enough
so that you can spend all your time translating coordinates,
and none drawing.
Ways of dealing with this:
1) Not correct event->x, event->y for the app, make
the app ask for the new coordinates. There are tricks
you can play here to make this quite efficient....
when you get a synthetic configure notify, mark
the position as unknown, but if you get a
real configure notify, or any mouse event on
the window mark it known. (Mouse events on the
window allow computation of the position by
the difference betweeen x,y and x_root,y_root)
The ICCCM recommends doing something like this.
Unfortunately, this breaks compatibility and is just
a sucky interface for the app.
2) Use the last x, y received for the event, then queue
an idle with a priority lower than events in which
you actually call XTranslateCoordinates() and
synthesize a pure-move ConfigureNotify if the
x, y you retrieve are different than the last x,y.
This should work quite well since synthetic
configure-notifies received are almost always pure
resizes, though there is still a round-trip request
involved.
[ A variant you could do on this with a sufficient
sophisticated X protocol lib (XCB?) would be to
send a TranslateCoordinates request immediately,
but don't block for the response; when the response
receives synthesize a pure-move ConfigureNotify
if necessary ]
I think 2) may be worth implementing, though opaque resize
over a slow link may be considered a bit of an edge
case so there is no rush.
Anyways, that's my X performance note for the evening,
Owen
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]