stress-testing glitz, cairo and librsvg
I wanted to see how brutal I can be to glitz, cairo and librsvg by not using any buffering via image-surfaces rendering everything straight as svg. This is the example and its sysprof-log. I make this available for the sake of putting out a small but heavy test-case for the cairo-hackers (or the developers behind librsvg). It opens a transparent and decoration-less window and renders 11 svg-icons. Moving the mouse-pointer over them causes a OSX-dock-like effect, where the icon under the pointer gets scaled up and a title blends in above it. All other icons are rearranged accordingly. Each svg-icon is transformed using a cairo-matrix and finally rendered via librsvg. The scaling is triggered by the mouse-motion-event. While I expected this to be a bit of work for the CPU/GPU (using glitz-enabled cairo 1.1.6 here), I never thought it would max out that much. I’m running on an Athlon64 3700+ alongside a GeForce 6600 under Xgl/compiz. Why does this turn out to be such a burden for the CPU? Where’s the bottleneck? I hope someone can point out to me what’s wrong.

just the rects, fast (click to play back, ogg/theora, ~270 KBytes)

full svg-glory, dog-slow (click to play back, ogg/theora, ~600 KBytes)
ATTENTION… it is highly unlikely that I will make a full dock-like application for gnome (or plain gtk+) out of this. This time I will stay strong and resist any forces that attempt to lure me into doing this. It happend with cairo-clock. But not this time *g*. Of course it does by no means prohibit anybody else to pick it up and do so.
June 7th, 2006 at 3:28 am
MacSlow dit it again
OH please please please please please please please please please please please do build a gtk+ dock out of this
I beg you!!!!
keep going MacSlow, im a huge fan of what your doing here
June 7th, 2006 at 4:04 am
Hi Marco, tudo bom?
I remembered having read something similar to that problem in planetgnome. After a bit of investigation I found this:
http://primates.ximian.com/~federico/news-2006-04.html#limiting-your-repaint-rate
Maybe it’s an explanation or a solution.
Good luck. Até mais.
June 7th, 2006 at 5:53 am
I reckon it’s the integrity issues of X and nvidia driver, not to imply that cairo is pretty "raw" and not yet mature or optimized. I found this perfomance comparison http://www.xaraxtreme.org/about/performance.html
By the way, it would be so sick to see a fully 3D desktop with docking, clock widget, imagine a real or better Mac experience on Linux. I think I shouldn’t lure you to this temptation, rite ;)?
June 7th, 2006 at 8:44 am
Hi Marco,
This app looks really great! Maybe I will make a OS X like dock bar of it.
This maxes out your cpu because on _every_ mouse move event you recalculate the size of the icons and their position. And I can tell you, there are a lot of mouse move events. To solve this problem, I think you need to add something like a counter in the mouse move event handler. Let it add every event, and only recalculate when the counter = 100 for example. Or you could use cpu ticks for it.
Good luck,
Frank
June 7th, 2006 at 9:07 am
Something like this should work:
gboolean on_motion_notify (GtkWidget* pWidget,
GdkEventMotion* pMotion,
gpointer data)
{
int newtime = 0;
static int oldtime = 0;
g_fMouseX = pMotion->x;
g_fMouseY = pMotion->y;
newtime = pMotion->time;
if(oldtime == 0)
oldtime = pMotion->time;
if(newtime > oldtime + 500) {
recalc_scales (g_aIcons, SVGS, g_fMouseX);
recalc_positions (g_aIcons, SVGS, 2.0f);
gtk_widget_queue_draw (pWidget);
oldtime = newtime;
}
return FALSE;
}
Although it doesn’t completely solve it, it’s a bit better already.
June 7th, 2006 at 9:18 am
@all: Thanks for the comments and tips sofar (here and via eMail)! I’ll add repaint-throttleing and surface-buffering with the next revision.
June 7th, 2006 at 9:34 am
You complete GIT! You beat me to it, although I was going for a pygtk version, and waiting for composite support to come back into pygtk before I even made an attempt. You may want to take a look at http://jrgraphix.net/research/flash-dock-mx-2004.php which was the code I was going to base mine on.
As far as the speed is concerned, I think there are a couple of contributing factors, firstly nvidia _STILL_ doesn’t have TFP support and my 6800GT runs slow on some compiz effects, because its using software rendering, and also the gconf key /apps/compiz/general/screen0/options/detect_refresh_rate and refresh_rate keys can sometimes be in error, setting the detect to false and the refresh_rate to the same as preferences -> screen resolution says generally increases speed quite a bit.
Apart from that it be wicked, and I may hack some code back into this one for fun at some point.
Would you mind if I set up a public SVN for people to use to hack on this?
Please reply to me via email cheers.
June 7th, 2006 at 10:13 am
Or you could use something like the timer Bahdad used for frame rate limiting in VTE (as used by the Gnome Terminal) which limits output to 40FPS.
g_timeout_add (25, function, data);
June 7th, 2006 at 11:44 am
Alan, also Federico Mena-Quintero wrote something about that:
http://primates.ximian.com/~federico/news-2006-04.html#28
June 7th, 2006 at 11:49 am
The most simple optimization is to request motion-hints instead of dealing with motion events. All you need to do is to add GDK_POINTER_MOTION_HINT_MASK to your window. Then, in the motion event handler, do not use the mouse position from the event struct but query for the current pointer position by calling gdk_window_get_pointer(). See the docs for GdkEventMask for more information.
June 8th, 2006 at 1:00 pm
I wanted to make this thing but I got this error:
gcc -Wall -O3 -march=k8 -DXK_MISCELLANY -DXK_LATIN1 `pkg-config –cflags glitz-glx cairo gtk+-2.0 librsvg-2.0` -c -o main.o main.c
main.c:41:32: error: librsvg/rsvg-cairo.h: No such file or directory
main.c:88: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘g_DimensionData’
main.c: In function ‘render’:
main.c:164: warning: implicit declaration of function ‘rsvg_handle_render_cairo’
main.c: In function ‘main’:
main.c:332: warning: implicit declaration of function ‘rsvg_handle_new_from_file’
main.c:332: warning: assignment makes pointer from integer without a cast
main.c:333: warning: implicit declaration of function ‘rsvg_handle_get_dimensions’
main.c:333: error: ‘g_DimensionData’ undeclared (first use in this function)
main.c:333: error: (Each undeclared identifier is reported only once
main.c:333: error: for each function it appears in.)
make: *** [main.o] Error 1
How to fix? :S
Thanks
June 8th, 2006 at 4:44 pm
@Hylke: *cough.cough* Install librsvg 2.14.x and related development-files.
June 8th, 2006 at 11:20 pm
Got it working, thanks.
June 9th, 2006 at 12:39 am
/usr/bin/ld: ne peut trouver -lGLU
June 9th, 2006 at 1:59 am
@setenza: Il n’y a aucun besoin de -lGLU. Tu peut le laisser tomber. (I hope I did not totally screw that up… for me french is magnitudes more difficult than english).
June 12th, 2006 at 10:28 pm
Working thanks