[cairo] changed semantics of cairo_destroy

Benjamin Otte otte at redhat.com
Tue Aug 31 01:53:34 PDT 2010


On Tue, 2010-08-31 at 01:59 +0300, M Joonas Pihlaja wrote:
> > I think this change warrants an explicit notice in the release notes
> > for 1.10, as it is certainly something for Cairo users to be aware of
> > and I didn't see the change announced in one of the 1.9.x snapshot
> > notes.
> 
> We discussed this change (on the irc channel #cairo, not on the 
> mailing list, sorry!) and decided in the end to drop flushing from 
> cairo_destroy().  As far as I recall the main motivation was that 
> applications are making lots of very short lived cairo_t objects and 
> flushing the surface was causing a lot of needless overhead, 
> especially considering that apps should be using cairo_surface_flush() 
> in all the right places anyway (since cairo 0.9.0.)  The feeling was 
> that it's not technically a change in the API since the 
> cairo_destroy() documentation doesn't actually say anything about 
> flushing surfaces, even if it is an actual change in behaviour.
> 
It's interesting that the win32 surface works as well as it does,
because Gtk 2.x interchangably renders using Cairo and native calls all
the time. So creating a cairo_t, rendering to it, then switching to
direct rendering using GdkGC, then continuing to render to the cairo_t
is the normal way of doing things.
So a surface flush only in destroy() will not help things.

Or in other words: If the X11 backend would do flushing, all programs
would be broken right now and the disro maintainers would hunt you with
pitchforks...

Note that GTK 3 will not have these issues, because all drawing is done
using Cairo.

> > By the way, I proposed a patch in Gtk+ to overcome this problem by adding a
> >     cairo_surface_flush (cairo_get_target (cr));
> > before every
> >     cairo_destroy (cr);
> > where relevant. Is this the correct approach (it certainly resolves
> > the bug I was seeing), 
> 
> Yes, this would be a correct fix.  An even better fix would be to 
> flush the surface only before doing any non-cairo rendering.
> 
Just adding surface flushes in random places is not going to help at
all, because all the other places that interchangably render with GCs
and cairo_t will still not work. You could try adding a surface_flush()
after every cairo_destroy() in GTK and hope for the best, but you'd have
to do that everywhere, including the murrine engine.


Finally, I'd like to point out that the fault certainly lies with GTK,
it should have done those flushes all the time. But the fact that Cairo
didn't enforce them (in particular on X11) caused this to not happen...

Benjamin



More information about the cairo mailing list