Comment 44 for bug 655024

Revision history for this message
veldt (veldt) wrote :

My current theory is that the cairo routines murrine uses to draw shadowed text have become slower when using recent versions of cairo, such as version 1.10.0 in ubuntu 10.10 maverick. Probably not noticeable normally, except that with transmission-gtk running on compiz, this text rendering may be happening much more often than necessary, causing a dramatic slowdown in that app.

If this is correct, there are two solutions, or three, if you count cairo speeding up:

1) Reduce unnecessary re-rendering in transmission-gtk -- an issue for the app, gtk+, and/or the window manager compiz. This would likely speed up execution the most.

2) Speed up murrine's rendering of shadowed text.

3) See cairo bug.

Details for all three are linked here. I would like it if for point 1, someone could confirm or tell me how to check whether paused torrent cells in transmission-gtk are being rendered repeatedly.

Details/hints.

1) From track of this bug in cairo bugzilla (now redirected to an earlier bug):
https://bugs.freedesktop.org/show_bug.cgi?id=31589#c5
As to already-rendered items continuing to consume CPU (after a surface flush), the only reason why that would happen is if the application itself is actually rerendering the items, say due to a new expose event from the window manager. There are currently no secret elves in cairo to burn your CPU just because they can when you're not looking. :)

2) Advice from M Joonas Pihlaja, ending with links to complete code and a nice set of rendered shadows:
I looked at the cairo-trace you provided in some detail, and it seems that the slow bit is indeed using stroking to "shadow" text. A faster and more accurate method to create shadowed text is to render the content-to-shadow to a temporary surface first and then paint that to the target surface twice at slightly different offsets, something like this:

/* Render to a temporary surface (similar to your target surface). */
cairo_push_group(cr);

{
  /* render your text here with pango for example. */
}

text_pattern = cairo_pop_group(cr);

/* Drop the shadow. */
cairo_save(cr);

{
  double shadow_alpha = 0.5;
  double shadow_offset = 2; /* note: keep this an integer */
  cairo_translate(cr, shadow_offset, shadow_offset);
  cairo_set_source_rgba(0,0,0,shadow_alpha);
  cairo_mask(cr, text_pattern);
}

cairo_restore(cr);

/* Paint the text on top of the shadow. */
cairo_set_source(cr, text_pattern);
cairo_paint(cr);
cairo_pattern_destroy(text_pattern);

The technique is illustrated with code that's actually been run here:

http://people.freedesktop.org/~joonas/shadow.c
http://people.freedesktop.org/~joonas/out-shadow.png

3) This cairo bug is entitled "Performance regression in synthetic micro-benchmark [due to global stroke tessellation] ":
https://bugs.freedesktop.org/show_bug.cgi?id=28067