[cairo] Performance problem with ARGB32 on XRENDER
damian.frank at gmail.com
Fri May 8 14:46:37 PDT 2009
Hi, all. I have code that uses an ARGB32 image surface as a
backbuffer for drawing. When it is time to copy it to the window, on
X, I use cairo itself to do the copy on-screen; for the destination I
use a cairo surface created from an ordinary, default-visual Window.
The copy is done using a straight-up cairo_fill with the SOURCE
operator, nothing funky going on at all.
This had been working fine, but I discovered that on some
configurations, the copy into the Window is HORRENDOUSLY slow. Like,
it takes a second for a normal-sized window on fast hardware. You can
actually watch it fill row-by-row. This appears to be caused by slow
XRENDER performance on this platform. (It's an older xorg server
(7.1.1) using the nv driver.) Interestingly, things are perfectly
fast if I use RGB24 instead.
Okay, fine, maybe it's my fault for wanting to have alpha in my
backbuffer. Maybe I want too much. It's been said before. But maybe
it shouldn't matter -- after all, I am telling cairo to ignore the
source alpha by using the SOURCE operator in conjunction with an
So here's the weird part: If, when I copy on-screen, I create a
second cairo surface representing the source using
cairo_image_surface_create_for_data, create it as RGB24 and give it
the same bits as the already-extant ARGB32 backbuffer, and then use
this second surface to do the blit on-screen, performance is great!
This is my workaround for now, and I'm fine with it. But the thing is,
it seems to me that it should be possible for cairo to be smart enough
during the composite operation to realize that the source alpha is
being ignored and to set up the XRENDER composition such that it does
the same thing as it does for the 24-bit case. This should be a huge
optimization for those with bad XRENDER drivers, right?
Also, is my workaround safe to use? It does make me nervous having
two surfaces sharing a buffer.
More information about the cairo