[cairo] source-optimized surfaces
Vladimir Vukicevic
vladimir at pobox.com
Wed Jan 30 12:35:04 PST 2008
Howdy,
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
CGImage.
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