[cairo] [API] cairo_surface_create_similar_image() + mime-surface

Chris Wilson chris at chris-wilson.co.uk
Fri Nov 21 02:59:33 PST 2008

The second pass of the mime-surface. Against the advice of Benjamin and
Adrian (who advocated the simpler interface), I think we need the
flexibility of not having to specify the image size during the
mime-surface constructor.

Continuing my adventures with swfdec, I relented and decided to expose
the API to create an image surface for a target backend, e.g. within an
XShm segment for xlib or a DIB for win32. This time, my proposed name
for this function is cairo_surface_create_similar_image() in that is
akin to cairo_surface_create_similar() - which I believe is consistent
and should not causing naming conflicts within the bindings. Internally
there are a few semantics still to be worked through (principally
ensuring that the fencing works - something that warrants further
investigation if we can mix GEM+dri2 etc and for other backends that
want to cache textures/server resources etc).

On Wed, 2008-11-19 at 15:52 -0500, Joe Drew wrote:
> On Nov 19, 2008, at 4:25 AM, Chris Wilson wrote:
> > This pattern seems like a good fit for example usages like firefox,
> > which keeps a cache of on-screen images decompressed and all other
> > images compressed.
> Yes, mime-surface seems like a natural fit. There is at least one  
> problem with it as-is, though: Firefox loads images as they stream in  
> on the wire; right now, it looks like mime-surface would require me to  
> repeatedly remove and re-add the mime data to update it.

I'm not overly keen on this as currently cairo has no assumptions about
how the mime-data is organised, so I can't simply append new data
without having to copy. We might be able to avoid having to allocate a
new tag every time - but I'd rather get the basics right first ;-)

> Ideally, I'd be able to call a mime-surface function after receiving  
> data from the network that appends data to the mime-data, then  
> continues the decoding process. We also sometimes know the size of  
> images (and sometimes don't) when we're loading them, so we might or  
> might not provide that information to Cairo right away.

Ok, I've broken down the mime-surface into 4 distinct phases.

1. Constructor:
cairo_surface_t *
cairo_mime_surface_create (const char *mime_type,
			   cairo_mime_format_func_t mime_format_func,
			   cairo_mime_decode_func_t mime_decode_func);
which is passed a function to lazily set the format (or NULL) and a
function to lazily decode the image data (or NULL if you really want
to ;).

2. Query:
cairo_mime_surface_set_image_format (cairo_surface_t *abstract_surface,
				     cairo_format_t format,
				     int width, int height);
Either called before use (probably immediately after the constructor) or
from within the mime_format_func callback (which is called when cairo
requires the image size for either surface creation or for computing the
size of operation).

3. Decode:
typedef cairo_status_t
(*cairo_mime_decode_func_t) (cairo_surface_t *mime_surface,
			     cairo_surface_t *image,
			     cairo_rectangle_t *roi);

If we need the pixel data (i.e. the mime-type is not supported by the
target backend) then we obviously need to decode the data. The image is
created for the target surface using
cairo_surface_create_similar_image() and the decoder must at least fill
the Region-Of-Interest (and update roi with the region actually filled).
[This currently is unused, but added for when acquire_source_image()
gains roi support.]

4. Dispose:
cairo_mime_surface_dispose (cairo_surface_t *abstract_surface);
discards any caches (i.e. the allocated image surface if we've needed to
decode the pixel data).

So any more suggestions for improvements?

More information about the cairo mailing list