[cairo] Performance of rendering long, angled lines in Cairo

Giles Westerfield esoteric at washington.edu
Fri Oct 31 12:22:08 PDT 2008


Hello,

I am relatively new to Cairo and this is my first time using the mailing
list, so please be nice.

I'm currently using Cairo to create a HUD interface in a flight simulator,
and I'm encountering significant drawing performance issues in certain
situations.  Since my application is a HUD, it needs to be redrawn very
quickly, and the total drawing time must not exceed 16ms in order to
maintain a smooth 60fps experience.

Let me give you some specifics about my system:  I'm using multiple windows
PCs, ranging from a single core Pentium M laptop 1gig ram to a quad core
4gig ram desktop simulator, and this issue occurs on all of them.  I'm using
Visual C++ in Visual Studio 2008 Professional and am working with the
current 1.8.0 build of Cairo.  I got the binaries and includes from the GTK+
for Windows site.

My application draws many things onto the screen and is generally very fast,
but I've encountered situations where it takes absurdly long to draw
something very simple (i.e. 150ms to draw a straight line).  In particular
this performance issue generally occurs when long lines are drawn at an
angle across the screen, or when large shapes, such as a call to
cairo_rectangle to render a full screen (non-filled) square are drawn.  I
will further clarify a few cases where I've noticed performance issues.

First, I will share how I have set up my cairo environment.  I'm using Cairo
to render to an image buffer using 8 bit alpha.  The reason for this is that
I'm using OpenGL as a front end to examine the alpha values in the buffer
(either on or off) and draw each individual pixel to the screen in a single
color.  If this seems convoluted to you, just accept it for now.  Here's the
code I use to set up the context:

cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_A8, 1280,
1024);
cairo_t *cr = cairo_create(surface);
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_BOLD);
cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);

Now, on to the issues.  Note that the following timing is done on the single
core Pentium M laptop, but I've noticed similar behavior on the quad core,
and the fact that there is such a large difference between the cases
concerns me:

1. The first issue I mentioned having to do with long, angled lines is
manifested in the following way:  When I draw a single 5 pixel wide line
horizontally across the screen like so, it takes less than 1ms to draw:

cairo_set_line_width(cr, 5.0);
cairo_move_to(cr, 50.0, 50.0);
cairo_line_to(cr, 1230.0, 50.0);
cairo_stroke(cr);

However, if I rotate the line to a 45 degree angle, it takes anywhere from
80 to 200ms to draw:

cairo_rotate(45.0*3.14159/180.0);
cairo_set_line_width(cr, 5.0);
cairo_move_to(cr, 50.0, 50.0);
cairo_line_to(cr, 1230.0, 50.0);
cairo_stroke(cr);

At first I thought this might be due to antialiasing being enabled (which
might have a noticeable performance effect on long slanted lines), but I
added the specific cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); function
call when setting up the context, and it seems to make no difference.

2.  The second issue has to do with the seeming fact that calling
cairo_rectangle is much slower than drawing individual lines and rendering
each one separately.  For example, the following rectangle call takes over
200ms:

cairo_set_line_width(cr, 5.0);
cairo_rectangle(cr, 50, 50, 1180, 924);
cairo_stroke(cr);

...while drawing and rendering each line of the rectangle separately takes
0-50ms, whihc is still longer than I'd like, but significantly less than
rendering the whole rectangle at once:

cairo_set_line_width(cr, 5.0);

cairo_move_to(cr, 50.0, 50.0);
cairo_line_to(cr, 1230.0, 50.0);
cairo_stroke(cr);

cairo_move_to(cr, 1230.0, 50.0);
cairo_line_to(cr, 1230.0, 974.0);
cairo_stroke(cr);

cairo_move_to(cr, 1230.0, 974.0);
cairo_line_to(cr, 50.0, 974.0);
cairo_stroke(cr);

cairo_move_to(cr, 50.0, 974.0);
cairo_line_to(cr, 50.0, 50.0);
cairo_stroke(cr);

I'm hoping someone can shed some light on these issues.  I have no doubt
that you will receive better render times than my single core laptop did,
but do you notice differences in timing between the cases?  Does it have to
do with the way I'm setting up my context, or the particular cairo build I'm
using, or is there some function I should be using?  Could it have to do
with the fact that I don't always supply even integer values to the drawing
functions (like I did in the examples) so that Cairo is having trouble
drawing between pixels?  I'm hoping the answer is not that Cairo is just too
slow to maintain 60fps in simple 2D applications.  Any suggestions or help
would be much appreciated

Thanks!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.cairographics.org/archives/cairo/attachments/20081031/06bb49ca/attachment.html 


More information about the cairo mailing list