[cairo] support for external surface backends

Matt Sealey neko at bakuhatsu.net
Wed Jul 10 14:21:24 PDT 2013

On Mon, Jul 8, 2013 at 5:57 PM, Sebastian Reichel <sre at ring0.de> wrote:
> Hi,
> We have a Chinese lasercutter at our hackspace, which uses some
> obscure proprietary format. We are currently reverse engineering
> the protocol and have written a simple tool, which translates the
> format into svg using cairo. So far so easy :)
> But we also want to support translating the other way around. For
> this we thought about hooking into cairo as surface backend like
> this:
> -----
> cairo_surface_t *surface;
> cairo_t *cr;
> surface = laser_cutter_surface_not_part_of_cairo(some, params);
> cr = cairo_create(surface);
> do_some_cairo_stuff();
> -----
> The backend does not really fit into a default cairo installation
> and IMHO it does not fit into the cairo repository at all. Thus
> we would like to put it into an additional library, which implements
> the surface interface.
> The problem is, that the cairo API does not allow external surface
> backends if I'm not mistaken. I mainly see two reasons for this:
> 1. cairo_surface_type_t is a compile-time-generated enum in cairo's
>    sourcecode
> 2. cairo_surface_t and cairo_backend_t are not exposed in the
>    public API
> Are there any plans to make these kind of setups possible with
> cairo?

I never saw any plans but I'd be pleased to suggest a route to doing
it. I think cairo should support loadable backends - it would go to
solve this problem and also to mitigate the strange features that if
you compile in a backend to libcairo suddenly you end up with shared
dependencies. Any app wanting to use simple image surfaces or xlib
surfaces on a system with cairo compiled to use GLES suddenly then is
implicitly linked to GLES, EGL (maybe VG) and so on, which is rather
an odd circumstance (the net effect is that on the Ubuntu systems I
run, for example, building Cairo to use GLES means the entire GLES
stack ends up in the initramfs because of Plymouth's dependency on
libcairo - but Plymouth doesn't use Cairo EGL or GLES backends)

I don't advocate making externally developed backends available,
though, that requires fixing down a surface API and exposing it.
Having a patch which integrates your backend then building Cairo for
yourself should suffice, though. What should happen is when you try
and create a surface, cairo knows which backend to load at that point,
loads it (and pulls in dependencies if it's using dlopen) and then the
backend will work - or not. In the case it does not load, cairo can
essentially fail creating a surface on that backend.

Cairo backend detection is already supported by being broken into
separate pkgconfig files but the backends themselves are not separate,
soaking memory and dynamic linker time (and as above, maybe space
which increases boot time) which should probably eventually get
solved. Applications can know at THEIR build time which backends are
installed via pkgconfig so they should basically not be calling
backends without detecting their installation, and at runtime only the
relevant backends would be loaded for each application as per
build-time requirement of that application (by virtue of a
context/surface init).

Someone would need to map out the interdependency of initializing a
backend and what might be missing in the indirect functions associated
with it that need to be split.

Matt Sealey <neko at bakuhatsu.net>

More information about the cairo mailing list