[cairo] Bug with paint_with_alpha and perf issues when compositing with SOURCE

Antoine Azar cairo at antoineazar.com
Thu May 1 00:34:38 PDT 2008

Hey all,
I discussed this already with cworth and am looking for feedback on this
paint_with_alpha will return an "incorrect" result when used with a SOURCE
operator. According to the doc, paint_with_alpha is "A drawing operator that
paints the current source everywhere within the current clip region using a
mask of constant alpha value alpha. The effect is similar to
cairo_paint(), but the drawing is faded out using the alpha value."
So doing the following:
cairo_set_source_rgb (cr, 0.2, 0.6, 0.9);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_paint_with_alpha (cr, 0.5);

Should return a blueish color with a 0.5 alpha all over the surface with no
more trace of the previous contents. Currently, the blueish color is being
composited like an OVER operator. This is because we avoid the SOURCE
operator and replace it to accomodate different backends. So we implement
our own definition of SOURCE which is:

(src IN mask IN clip) ADD (dst OUT (mask IN clip))
//see _clip_and_composite_source in cairo-surface-fallback.c

According to the doc, in the paint_with_alpha case, this definition should
actually be:

(src IN mask IN clip) ADD (dst OUT clip)

Carl and I came up with a solution that I included in the attached patch. It
works nicely and corresponds to our doc. However it does worsen performance,
which is already terrible when compositing with a SOURCE operator. The
performance benchmark shows the paint_with_alpha-solid-rgb-source test is 10
times SLOWER than the over equivalent (you'd expect SOURCE compositing to be
faster than OVER). Quartz is 40 times faster than pixman on that test.

This patch will fix the rendering of paint_with_alpha, but we should look
into improving the performance of SOURCE compositing. I'm not sure how each
backend interprets it, but we shouldn't be penalizing all of them for
variations. The _clip_and_composite_source function really is painful to
look at for such a simple operation. Maybe we could have a composite_source
function in the backends, and fallback to pixman for the backends that don't
support it the way we define it. That would allow us to remove the nasty:

if (mask) {
/* These operators aren't interpreted the same way by the backends;
* they are implemented in terms of other operators in cairo-gstate.c

from _cairo_surface_composite and get really good speed ups both in the
backends and in pixman.

Comments and feedback welcome!

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.cairographics.org/archives/cairo/attachments/20080501/ea5cc65c/attachment.html 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0005-Fixed-paint_with_alpha-bug-with-SOURCE-operator.patch
Type: application/octet-stream
Size: 0 bytes
Desc: not available
Url : http://lists.cairographics.org/archives/cairo/attachments/20080501/ea5cc65c/attachment.obj 

More information about the cairo mailing list