[cairo] On fallback strategies (was Re: GSoC: Scan converting rasteriser update
Jeff Muizelaar
jeff at infidigm.net
Sat Oct 18 13:07:02 PDT 2008
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