[cairo] XShm

Chris Wilson chris at chris-wilson.co.uk
Mon Oct 22 13:04:21 PDT 2007


Well, I've been playing some more with XShm code and implementing the
suggestions that have been made - thanks!

What became most apparent when trying Vlad's
cairo_surface_acquire_image() suggestion for real with swfdec was the
lack of synchronisation with the XShmPutImage and especially whilst
using the XShmPixmaps (this ugly fact was hidden earlier by the
XSynchronize() within cairo-test). Adding the XSync() after the
XShmPutImage dramatically affects cairo-perf results.

After spending a short time tuning, the results are still quite mixed:
Speedups
========
 xlib-rgb&  paint_similar_rgba_source-256    0.43 0.31% ->   0.19 6.62%:
2.54x speedup
█▌
 xlib-rgb&        text_image_rgb_over-64     1.32 0.52% ->   0.54 0.23%:
2.47x speedup
█▌
 xlib-rgb&     fill_image_rgba_source-128    1.37 1.02% ->   0.58 0.91%:
2.34x speedup
█▍
 xlib-rgba&   stroke_image_rgba_source-256    8.23 0.35% ->   3.52
0.89%:  2.34x speedup
█▍
...
Slowdowns
=========
 xlib-rgb&      fill_image_rgb_source-256    1.76 0.29% ->   4.09 0.30%:
2.32x slowdown
█▍
 xlib-rgba&       text_image_rgba_over-128    0.84 0.11% ->   1.96
1.42%:  2.32x slowdown
█▍
 xlib-rgba&     text_image_rgba_source-128    1.38 0.80% ->   3.21
1.55%:  2.32x slowdown
█▍
 xlib-rgba&     text_solid_rgba_source-128    1.30 1.78% ->   3.01
1.19%:  2.32x slowdown

But better than the initial 20x slowdown for text with the paranoid
XSync'ing.

The branch adds two new APIs:

1) cairo_image_surface_create_similar() [what I previously called
cairo_image_surface_create_for_target(), but Benjamin Otte suggested a
better name] - allows the application to create an image surface that
purports to be optimized for the backend. For example, it may be placed
in a shared memory segment with the xlib backend (win32 support should
be even easier...). This is used internally within Cairo when allocating
image surfaces for gradient patterns.

2) cairo_surface_acquire_image()/cairo_surface_release_image() - Vlad's
suggestion for a convenient API to directly manipulate the bits
representing a raster surface (or failing that degrade appropriately to
pulling and pushing the pixels). Having experimented in using this API
with swfdec, it does provide an easier method for loading raw data into
Pixmaps.

For instance:
    image = cairo_image_surface_create_similar (cairo_get_target (cr),
                                                ...);
    load_pixel_data (cairo_image_surface_get_data (image), ...)
    surface = cairo_surface_create_similar (cairo_get_target (cr), ...);
    cr2 = cairo_create (surface);
    cairo_set_source (cr2, image, 0, 0);
    cairo_paint (cr2);
    cairo_destroy (cr2);
    cairo_surface_destroy (image);
reduces to:
    surface = cairo_surface_create_similar (cairo_get_target (cr), ...);
    cairo_surface_acquire_image (surface);
    load_pixel_data (cairo_image_surface_get_data (surface), ...)
    cairo_surface_release_image (surface);

Whilst the cairo_surface_acquire_image() is in effect it redirects Cairo
drawing operations on the surface to the backing image, so that the
application is free to mix normal Cairo commands with direct pixel
manipulation - at the expense of forcing the software implementation.

The patches have grown a little too large to be conveniently attached
and reviewed inline, so I've pushed it to my git repo at
git://annarchy.freedesktop.org/~ickle/cairo in the xshm branch. If you
can spare a few moments to review the API additions or find better ways
of synchronizing the images with the Xserver, please be my guest.
--
Chris Wilson


More information about the cairo mailing list