Brian J. Tarricone
brian at tarricone.org
Tue Jun 15 04:19:22 PDT 2010
I've been working on a small, hopefully-fast compositing manager that
uses OpenGL ES 2 on an embedded system to draw windows to the screen. I
noticed that moving windows around the screen was a bit jerkier than I
expected. This evening I was profiling using oprofile, and I found that
memcpy() was eating around 40% of my time while moving windows around.
If I did an oprofile run without moving windows, I see pretty much
nothing in the profile results, certainly no memcpy().
Oprofile wasn't behaving well enough (yay ARM) to get call stacks, so I
started playing around with gdb, attaching to Xorg. I was easily able
to get it to break inside memcpy() (ssh; sleep 5; sudo killall -TRAP
Xorg ... grab mouse and crazily move xterm around), and found that I was
in a stack that included compWindowUpdate() ->
compWindowUpdateAutomatic() -> CompositePicture() -> (other stuff) ->
This raised a red flag, because I know XRender isn't accelerated on our
platform (sigh), and memory bandwidth is a bit limited... so I'm not a
fan of excessive memcpy()s.
I thought the compWindowUpdateAutomatic() was a little odd, since I'm
using XWindowRedirectSubwindows(dpy, root_window,
CompositeRedirectManual). Jumping around in gdb, I was able to verify
that it wasn't the root window, but some child of a toplevel. So my
thinking was... why is it compositing (well, probably just copying)
windows onto their parents?
So I poked in xorg-server/composite/compwindow.c, compWindowUpdate(),
and found this snippet:
if (pWin->redirectDraw != RedirectDrawNone)
CompWindowPtr cw = GetCompWindow(pWin);
cw->damaged = FALSE;
What I'm wondering is -- why is that not checking:
if (pWin->redirectDraw == RedirectDrawAutomatic)
instead? My first thought was that maybe it was just copying child
windows into the Pixmap of the parent, but I haven't yet verified either
way. Regardless, none of the windows on the screen had changing
contents, so why would it need to be doing anything -- the only window
that should be changing relative to its parent is the toplevel xterm
window changing relative to the root window.
Unfortunately I haven't yet tested a change here, because my
cross-compilation environment is being uncooperative; I'll look into
fixing that tomorrow.
But: on my x86 laptop, I did try changing this line, and my X server
appears to still behave properly with (and without) a compositing
manager running. Tomorrow I'll try to rebuild Xorg for ARM and
re-profile to see what happens.
I also tried, for the hell of it, telling my compositor to redirect
windows, but then never paint anything, and I did get what I expect --
nothing on the screen but the root window. So clearly it's not actually
painting to the screen by itself when in RedirectManual mode.
If anyone could shed some light on what's going on here (I'm probably
just misunderstanding something!), that would be great.
FYI, I'm running xserver 1.6.4 on ARM (Ubuntu 9.10's version), and 1.8.1
on x86. They both seem to have the same code in this particular
function, though of course I'm not sure if they behave the same way wrt
the calling of that function.
More information about the xorg