X11 performance tests/results

127 views
Skip to first unread message

Marco Gidde

unread,
Oct 4, 2009, 10:12:39 AM10/4/09
to jazzscheme
Hi all,

1 Introduction
~~~~~~~~~~~~~~~
I try to summarize the tests I made to improve (or better track down
the cause of) the poor performance that some of us have seen with
Jedi on Linux/X11. The effect can be described as an pixel wise
redraw of the Jedi GUI, it is so slow that you can see it is painted
line by line. It does not seem to be a general problem though, as
Jedi runs pretty nice on an up to date Ubuntu installation (virtual
machine) here.

Guillaume gave me a hint how to turn off Jazz's double buffering
code and the updates were fast, but of course the whole screen was
flickering. So it all comes down to double buffering techniques.

2 Double buffering (offscreen drawing)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For those who do not know about this: offscreen drawing or double
buffering refers to a programming technique were, instead of drawing
into the window directly (which might flicker) you first draw into
an image and when done copy this image into the window. To make this
effective there has to be a *very fast* copy operation, but this is
probably the case for any windowing system, be it X11 (what I know),
Windows or the Mac.

2.1 Cairo images
=================
In Cairo one draws into surfaces and these surfaces *might* be
connected to some objects of the underlying windowing system. The
Jazz UI essentially creates two surfaces, one for the X11 Window,
and another with cairo_image_surface_create to get an image surface
for the offscreen drawing. In the end the image surface is used as
a source for the window surface and then drawn. This is very
idiomatic code and should just work, but doesn't on all
platforms. The drawing itself is fast, as shown with turned of
offscreen code, so Cairo obviously misses the aforementioned fast
copy operation.

2.2 Cairo push/pop group
=========================
Another approach to get double buffering with (not too old versions
of) Cairo is the Cairo_push_group/cairo_pop_group_to_source pair of
functions. I tried it out by first turning of Jedi's own offscreen
code and then decorating the function with-platform-painting with a
push/pop. The good news is, that there was no flickering, the bad
news that it also suffered from the pixel wise redrawing problem.

2.3 Plain X11 style
====================
In old style X11 programming double buffering looks like this: you
create an X11 Window with XCreateWindow or the like, create a
Pixmap with XCreatePixmap, draw into this Pixmap and finally do the
fast copy with XCopyArea. Window and Pixmap are so called Drawables
and XCopyArea copies from one Drawable to another. I did not test
this, cause I used it often enough to know that it Just Works.

2.4 Plain X11 style adapted to Cairo
=====================================
Cairo offers the function cairo_surface_create_similar which gets a
Cairo surface and should create an image surface with very similar
properties (color depth etc.) Additionally there is a function to
access the underlying Drawable. With these we have everything at
hand to perform a XCopyArea.

The first surprise: cairo_surface_create_similar expects a second
argument (a cairo_content_t) and when fed with
CAIRO_CONTENT_COLOR_ALPHA the Drawable is 0, so no usable Pixmap at
all.

Using CAIRO_CONTENT_COLOR one gets a Drawable and with XCopyArea
the result is as expected: fast and flicker free updates. *But*:
the times between these updates are now unreasonable high, so now
Cairo's wastes its time somewhere else. Either the drawing routines
that operate on the "similar" surface are much slower than directly
drawing into the window, or Cairo does some other strange
conversions somewhere.

3 Conclusions
~~~~~~~~~~~~~~
I tried Jedi with several versions of Cairo (not all mentioned
setups though) and it made no difference so updating this library is
probably not a solution. The only thing left is the X server itself
and the fact that Jedi runs nicely on the mentioned Ubuntu virtual
machine supports this suspicion.

The last test was to compile the Cairo sources on my computer and
see what happens. The result was the same until I configured Cairo
with --enable-xlib-xrender=no. With this switch the redrawing was
similar to the [Plain X11 style adapted to Cairo] setup, i.e. slow
drawing but fast updates. So it seems that Cairo does not work well
with older X servers (here: X.Org version: 6.9.0) and misses some
important optimizations in this case.

All in all I would not recommend any changes to the Jazz UI sources,
because it is a specific Cairo/X11 combination that leads to the
problems, not Cairo or X11 per se.


[Plain X11 style adapted to Cairo]: sec-2.4

4 Workarounds
~~~~~~~~~~~~~~

4.1 Turn of double buffering
=============================
If someone can bear the flicker (I can't), turning of the offscreen
drawing might be an option. But one should be aware that it is
quite hefty since Jedi currently redraws more than it has to.

4.2 Turn of Cairo's XRender code
=================================
As mentioned above, compiling Cairo with --enable-xlib-xrender=no
gives not a great but a reasonable and workable result. I will stay
with this until I am able to update X11 as a whole.


Regards, Marco

Guillaume Cartier

unread,
Oct 13, 2009, 3:16:25 PM10/13/09
to jazzs...@googlegroups.com
Hi Marco,

First of all, many thanks for such an exaustive analysis of the
problem! It is very difficult and frustrating to try and debug a
problem like this without access to reproducing it but your help sure
goes a long way!

After reading your email, it seems to me the most promising approach
is using cairo_surface_create_similar. It seems the right API to use
if Cairo is to know that it can use XCopyArea. And your results of
fast and flicker free updates seem to indicate it is indeed the right
approach.

The next step then would be to identify why the times between updates
become larger. Did you try running statprof to see if it is a Jazz
problem? One thing that is not implemented 100% correctly in Jazz is
the event loop that doesn't do an OS wait on events (this needs
evolutions in Gambit that are planned but not high priority at the
moment) and maybe that is what is causing the times to become larger?

Using statprof is very easy. Just insert (start-profile) ...
(stop-profile) pairs where you need it. Run the code and then in the
Profile Results palette hit the Refresh button. You'll have a complete
profile with % where the time was spent. I suggest you make jedi after
putting the calls to statprof and they work as you want as statprof
works best with compiled code.

Another thing. Did you try asking the experts on #cairo in IRC to be
sure for instance if cairo_surface_create_similar should result in
fast copies on all X11 platforms? (or any other advice)

Lets get that ... of a bug!

Guillaume

Marco Gidde

unread,
Nov 8, 2009, 8:54:59 AM11/8/09
to jazzs...@googlegroups.com
Hi Guillaume,

sorry for this very late reply.

Please don't waste your time with this "bug" and continue your fine work
on Jazz/Jedi by adding features, cleaning up code or even optimizing the
drawing routines (I think I mentioned already, that the UI redraws too
much). Of course you could try to use cairo_surface_create_similar to
then enforce XCopyArea, but as my tests indicate, you will just run into
another *cairo* inefficiency.

One more simple test I made a few hours ago (almost a shame I did not
come up with it much earlier): I removed the self compiled libcairo from
my system and recompiled Jedi. As expected the redrawing was pixel wise
and therefore slow. I went to another (real but old) Linux computer with
an Ubuntu 9.4 installed (i.e. a more up-to-date X server), opened a
session via 'ssh -X' on my main computer and started Jedi - everything
runs fine and smoothly! I.e. by just using another X server the problem
went magically away.

Maybe you could start a poll on the list to find out how many Linux
users are out there and how many of them really suffer from this
issue. In the meantime there is no reason not to officially release
Jazz/Jedi, in any case not because of this - just put a note on the
website that there are known problems with *very* old X servers on
Linux.

To say it again: don't waste your time with a bug that is not yours and
that can only be fixed by fixing cairo - for a version of an X server
that is pretty much outdated by now.


Regards, Marco

Reply all
Reply to author
Forward
0 new messages