[cairo] source-optimized surfaces

Vladimir Vukicevic vladimir at pobox.com
Wed Jan 30 12:35:04 PST 2008


I've got a patch (sitting in https://bugzilla.mozilla.org/show_bug.cgi?id=414685) 
  that creates a new surface type for Quartz, that I'm calling a  
quartz_image surface.  This optimizes internal storage to a form  
(CGImageRef) that quartz can render quickly from as a source.  As a  
bonus, this also happens to be a quick way to load bitmap data into a  

The API I'm using here is:

cairo_quartz_image_surface_create (cairo_surface_t *other);

Where |other| must be a cairo image surface.  There's also an associated

cairo_surface_t *cairo_quartz_image_surface_get_image(cairo_surface_t*)

to retrieve the image surface that's backing this.  With changes in  
the Quartz surface to know about this surface, this yields speedups of  
around 30x when rendering images.

Note that there are two different issues here:

1) Speed up loading of bitmap data into cairo surfaces;

2) Create surfaces that can be used in an optimized way by some  
backends when used as a source.

The XSHM work earlier only touched on #1; #2 isn't necessarily an  
issue on X, because there isn't a more-optimized source type than the  
X types that are already in use.  On Windows, #2 is also not really an  
issue, since you can both load into a win32 surface quickly and use it  
as a source quickly, though there could be some reduction of resource  
usage if there was a source-optimized surface (wouldn't need to store  
HDCs, clipping regions, etc.).

However, on Quartz, #2 is pretty huge -- and I expect it to be an  
issue in any future OpenGL, DirectX, etc. backends.  These would all  
be optimizations; all these surfaces should always work as a source  
and as a destination, though with different performance characteristics.

I'd like to propose that these be done as new surface types, and that  
they have API that makes sense on a case-by-case basis (instead of  
trying to come up with a unifying API framework).  For example, on  
quartz, the memory is directly shared by the CGImage and the image  
surface, so no additional API is needed there.  For something like  
OpenGL though, you may pass in an image surface to the create function  
to create a texture with those contents, but would then need to call  
some kind of update(cairo_surface_t *surface) function to replace the  
contents with new data, or update_subrect() etc.

    - Vlad

More information about the cairo mailing list