[cairo] On fallback strategies (was Re: GSoC: Scan converting rasteriser update

Behdad Esfahbod behdad at behdad.org
Sat Oct 18 13:52:32 PDT 2008

Thanks Jeff.  I think we are pretty much on the same page.


Jeff Muizelaar wrote:
> On Sat, Oct 18, 2008 at 02:52:40PM -0400, Behdad Esfahbod wrote:
>> Jeff Muizelaar wrote:
>>> The UNSUPPORTED model becomes problematic as soon as a backend wants to
>>> implement one of these methods previously unimplemented methods.
>>> Fallbacks are a all-or-nothing choice, so implementing anything that
>>> uses some of the previous fallback is difficult. This makes adjusting
>>> the behaviour of a fallback difficult for a backend.
>> Using UNSUPPORTED does not mean we can't have
>> _cairo_image_fallback_do_some_part_of_filling_and_just_that().
>> It's not either/or.  Define UNSUPPORTED as calling cairo_surface_fallback_XXX().
> I agree. I just wanted some consensus about UNSUPPORTED not always being
> the right thing to do, especially when different backends want to
> implement an operation in different ways.
>>> Further, I don't see why one would have to copy paste a lot of cruft
>>> when we can have a utility function that's called. There's no reason a
>>> fill() implementation would need to be anything more than a single
>>> function call.
>> I'm talking about that single-line function that needs to be copied in 12
>> different backend files, and modified every time the backend signature changes.
> I'd gladly trade that for greater code readability. I read the code more
> often then the backend signature changes and I don't see the duplication
> being a source of bugs. But I do agree, if we end up in a sitatuation
> like you describe, something's wrong.
>>> That's not really true; you do need to worry about what happens. If you
>>> have a backend that doesn't implement fill() you have to implement
>>> composite_trapezoids(). composite_trapezoids() certainly isn't the only
>>> logical operation to implement fill with, a backend end could, for
>>> example, want composite_spans(), composite_flattened_polygon() or
>>> composite_non_intersecting_polygon(). We wouldn't want to probe each
>>> backend for each of these possible operations. 
>> Sure, some operations may be better fallbacked using a function calling helper
>> functions.  But for show_glyphs for example, there's no way to do it cleaner
>> than using UNSUPPORTED.  The way it works currently is:
>> cairo_surface_show_glyphs:
>> 	try surface_backend->show_glyphs
>> 	cairo_surface_fallback_show_glyphs
>> 		cairo_scaled_font_show_glyphs
>> 			try font_backend->show_glyphs
>> 			create a mask, add glyphs to it and paint it
> I don't advocate eliminating the UNSUPPORTED idiom entirely. If it makes
> more sense for an operation to return UNSUPPORTED then we should
> certainly keep it. I don't want to be dogmatic about it. Right now I
> mostly care about fill() and stroke() and don't think the fallback
> structure makes sense for backends that aren't XRender-like. I haven't
> really thought about the other operations much yet. 
>> Currently the backend interface has like 15 methods, many backends implement
>> only five of them.  How does adding ten one-line functions make it more readable?
> One of the things it could potentially do is eliminate is some of the backend
> interface methods. For example, fill_rectangles() and
> composite_trapezoids() could go away. However, I too don't want to end
> up in a situation where a backend has to implement ten one-line
> functions.
> Any changes related to this should be gradual, so we should be able to
> evaluate each circumstance as needed.
> -Jeff

More information about the cairo mailing list