[cairo] Best strategy for complex screen drawing

Timothée Lecomte timothee.lecomte at ens.fr
Sun Nov 20 15:20:26 PST 2005


Dear Cairo specialists,

I am currently working on a so-called "terminal" for gnuplot, based on
Cairo (and also wxWidgets and pango by the way). gnuplot is a program
which plots data or functions, either in 2D or 3D. The terminal itself
is intended to render to the screen commands like 'draw a line', 'draw a
polygon', that are produced by the core gnuplot code.
I have chosen Cairo to handle the drawing part as it has powerful
capabilities, mainly line antialiasing, which gives good-looking plots.
Cairo also seems to be a good choice to build a cross-platform program,
as it provides generic image buffers and specific backends for X11,
Windows, and probably more in the future. Finally, my code could also be
reused to give ps/psf/png/... outputs easily.

In practice, my concern is that I would like to reach reasonable drawing
speed with a large number of polygons (this number is around 10000 for a
complex plot).

Such a drawing with ~10000 polygons (in cairo : filled paths made of 4
lines) takes approximately 5 seconds with a generic image surface or a
xlib surface created by gdk (via gdk_cairo_create).

Each time the window is resized, I draw the surface again (mainly
because I don't want the text to be scaled, nor the linewidths). Thus, I
never use scale transformations.

And, of course, I have to handle expose events.

These requirements made me choose to draw to an offscreen surface
(initially and when the window is resized) and to copy this surface to
the screen when it is needed (expose events). That's why I would like to
have help to choose the best components for this scheme.

I have used so far an image buffer
(cairo_image_surface_create_for_data), and I copy it to the screen when
needed (ie for expose events) by converting to a bitmap that wxWidgets
knows how to handle. The conversion of the image buffer to a wxwidgets
bitmap doesn't need much time compared to actual drawing done by cairo.

Here are the main questions :

1) Would it be more efficient to use a gdk/cairo surface for the screen
(via gdk_cairo_create) and use cairo_set_source_surface to copy the
image surface to the screen ? (instead of the image buffer conversion) I
suppose the answer is no.

2) Would it be more efficient to use a specific backend ? For example,
should I draw to an offscreen Xlib pixmap, and use it as a source
surface ? Will I benefit from possible render acceleration ?

3) Are there other solutions that I might have forgotten ?

Thanks for your help, and thanks for the beautiful library cairo is !

Timothée Lecomte


More information about the cairo mailing list