[cairo] Creating an opaque fade-in effect with Cairo

Tristan Schmelcher tschmelcher at google.com
Mon Jan 24 13:20:49 PST 2011

On 21 January 2011 10:28, Tristan Schmelcher <tschmelcher at google.com> wrote:
> On 21 January 2011 00:26, Andrea Canciani <ranma42 at gmail.com> wrote:
>> On Fri, Jan 21, 2011 at 1:59 AM, Tristan Schmelcher
>> <tschmelcher at google.com> wrote:
>>> On 20 January 2011 14:26, Andrea Canciani <ranma42 at gmail.com> wrote:
>>>> On Thu, Jan 20, 2011 at 10:54 PM, Tristan Schmelcher
>>>> <tschmelcher at google.com> wrote:
>>>>> Hello,
>>>>> I am developing a Cairo-based application and I'd like to fade-in an
>>>>> opaque image on top of a background. i.e., I want the image to start
>>>>> out as opaque black and gradually fade-in to its full brightness. But
>>>>> I can't figure out how to efficiently paint my image surface to the
>>>>> screen and attenuate the RGB channels at the same time. Ideally I'm
>>>>> looking for an API that lets me paint my source surface (the image)
>>>>> and takes a fractional brightness parameter in the range [0, 1] to
>>>>> multiply with each of the R, G, and B channels. So far the best that I
>>>>> have come up with is to first paint with CAIRO_OPERATOR_CLEAR and then
>>>>> paint with CAIRO_OPERATOR_OVER and cairo_mask(), but that seems like a
>>>>> lot of computational work. Is there a more efficient way to do this
>>>>> with Cairo?
>>>> If your destination is always opaque, you can do everything like this:
>>>> cairo_set_operator (cr, CAIRO_OPERATOR_IN);
>>>> cairo_set_source (cr, the_fading_surface);
>>>> cairo_paint_with_alpha (cr, the_fade_parameter);
>>>> This should be sufficient to completely replace the old content assuming that
>>>> the destination has a content of type CAIRO_CONTENT_COLOR.
>>>> It is slightly less flexible than your code, because this will only allow
>>>> fading from/to black, but I expect it to be faster, because it performs only
>>>> one compositing operation.
>>> Thanks for the info! My destination is indeed of type
>>> CAIRO_CONTENT_COLOR, so your suggestion works great, but surprisingly
>>> it seems to be slightly slower. When I make it render as fast as it
>>> can, the CLEAR+OVER approach gets an average of 13 fps while the IN
>>> approach gets an average of 12 fps. Rather strange ... I definitely
>>> agree with you that it ought to be the faster method.
>> This probably means that with CLEAR+OVER you were hitting a fast path
>> in pixman, but with IN you are going through a slow path.
>> Profiling should tell you if this is what happens.
>> A trace would make it possible to cairo/pixman developers to try and reproduce
>> the problem. See http://www.cairographics.org/FAQ/#profiling for reference.
> I'll try that. Thanks. :)

So I spent some time trying to generate a trace with cairo-trace, but
my application is a browser plugin so the tool also captures the Cairo
calls made by the browser. :( I tried hacking up libcairo-trace.so to
get just the traces relevant to my app but I didn't manage to get any
usable output. Sorry. :/

OTOH, my browser plugin is open-source so if you'd like you can see
exactly what I'm doing:
RendererCairo::Paint() is where all the work happens.

This opaque fade-in effect isn't our top priority performance-wise
though, so for now we're just going to use CLEAR+OVER.

>>>> You should obviously profile your application to check if this improves
>>>> its performance or not and you might also want to check what are the hot
>>>> functions, so that they might possibly be improved.
>>>> Andrea

More information about the cairo mailing list