[Qt-interest] modifying qx11mirror graphics dojo example for better performance

Thomi Richards thomir at gmail.com
Wed Sep 16 16:51:07 CEST 2009


Hi,

This could be a long post - I apologise in advance. I'm writing a Qt
application where I need to keep a reasonably up-to-date QPixmap that
contains the current user's desktop (that is, X11 root window and all
child windows). I can get a one-time snapshot of the desktop using
this code:

<snip>
QDesktopWidget *w = QApplication::desktop();
if (w)
{
    QRect r = w->screenGeometry();
    QPixmap p = QPixmap::grabWindow(w->winId(), 0, 0, r.width(), r.height())
    QByteArray bitmap;
}
</snip>

However, this is really slow. On my machine this call takes around 800
ms. so I started looking at the code for the "qx11mirror" graphics
dojo example (svn://labs.trolltech.com/svn/graphics/dojo/qx11mirror).
This app is pretty simple. It uses the X11 call "XRenderComposite" to
grab the target window and store it in a QPixmap. It also uses the X11
XDamage extension to get notifications of when the target window is
damaged. However, it does this using the "XDamageReportNonEmpty" mode,
which just notifies the app whenever the window state changes from
undamaged to damaged. I've been modifying the dojo example a bit, such
that:

QX11Mirror::pixmap() becomes trivially simple:

<snip>
QPixmap QX11Mirror::pixmap() const
{
	return m_px;
}
</snip>

I change the XDamage reporting method to be
"XDamageReportRawRectangles", which will send us a list of the
rectangles that have been changed.

Finally, in the "void QX11Mirror::x11Event(XEvent *event)" (where the
XDamage events are recieved), I'm attempting to copy only the
rectangles that have changed to the local pixmap (m_px). However, I'm
having some issues. I'm running my modified qx11mirror application
with the winId of 0, which is the root window. Even with my changes it
still seems very slow. The code I'm using for my changes can be seen
here:

http://cpp.pastebin.com/m1524fb39

I'm no X11 expert (far, far from it), and I don't know whether I
should be asking this here or perhaps on an X11 list. My questions
are:

First, I can't seem to get X11 to write to my cached pixmap directly
without blanking out everything that's not been updated (unless I copy
everything, but that's what I'm trying to avoid). So Instead I'm
drawing updates to a temp pixmap, and then copying those across to my
cached image using a QPainter. I'm sure this isn't helping the
performance problem at all.

Second, I've found a very nice KDE tutorial about using XDamage &
XRender. It looks like the inspiration for the tutorial was qx11mirror
(or something very similar). The tutorial can be found here:

http://ktown.kde.org/~fredrik/composite_howto.html

It's a great tutorial, but one but in particular confuses me. It states:

"""
Note that in the above example all the damage is subtracted from the
window, but the actual damage region is thrown away. In this example
the damage region is retrieved from the damage object, and set as a
clip region for the picture:
"""

I've tried implementing the code listed to set a clip region for the
XComposite call (you can see evidence of this in my code paste above),
but try as I might I just can't get the clip mask to work properly.

I'm hoping that someone on this list can give me a few pointers. I
realise that the problem is probably more related to X11 than it is to
Qt, but I'm hoping, since I'm modifying an existing Qt example that
someone will take pity on me and show me the light ;)


Thanks,



More information about the Qt-interest-old mailing list