[cairo] Performance issue with cairo-1.10

Siarhei Siamashka siarhei.siamashka at gmail.com
Tue Nov 2 16:06:08 PDT 2010

On Sunday 31 October 2010 17:26:32 Holger Hans Peter Freyther wrote:
> Hi all,
> one of my applications is consuming a lot more CPU time after upgrading
> from cairo-1.8 to cairo-1.10. According to oprofile and manually
> 'sampling' with gdb it spends a lot of time in _draw_image_surface and
> there in the 'slow' path calling _field_to_8.
> My setup is a PXA270, running Xfbdev (tinyX/kdrive) with a native depth of
> 16bpp. In the demonstration application I am using a GtkDrawingArea, create
> a RGB24 image_surface and then try to paint the image on the surface
> allocated by GDK (obviously backed by xlib).
> My understanding goes so far that the cairo_paint call in the expose_event
> will create a new surface and then copy/draw the image surface.
> Let me explain where I think stuff is going wrong.
> In _cairo_xlib_surface_clone_similar we deal with a
> _cairo_surface_is_image(src) and then call
> _cairo_xlib_surface_create_similar.
> Now the xlib surface used by the GDK Window has a xrender_format set and
> the depth of it is 16bit and both this surface and the image surface have
> the same content.
> This means that:
>     if ((xrender_format != NULL &&
>         _xrender_format_to_content (xrender_format) == content)
> will evaluate to true and a xlib_surface with 16bit depth and the visual of
> the original GDK surface is used. The call to _draw_image_surface will now
> try to draw a 24bpp image to a 16bit surface through the slow path.
> The workaround for the application would be to use the ARGB32 format to
> make the content not match and then the 24bpp can be copied using the fast
> path. To make this a regression cairo-1.8 is using a 24bpp surface to copy
> the image surface.

There seem to be 3 cases in _draw_image_surface, depending on what format
you use for cairo_image_surface_create in your example:


In this case 'surface' is using 16bpp format. There is something wrong with not 
using pixman for conversion (pixman is only used if _pixman_format_to_masks 
returned error). So it ends up running a naive C loop. If it actually used
pixman, I would assume that the performance might be comparable to case (2).


In this case 'surface' is using 32bpp format with alpha channel. Cairo has no 
extra overhead. But the actual conversion to 16bpp happens in X server via
'over_8888_0565' pixman fast path.


In this case both 'surface' and your image are using 16bpp format. Everything 
is fast, or at least should be fast.

> Was this change intentional? What options exist to find a fix in cairo
> itself?

Latest cairo release got support for 16bpp format because it is faster on the 
devices which are using it as a native color depth. Even when there is a choice
between 16bpp and 32bpp, 16bpp is often faster on the devices with slow memory.

Best regards,
Siarhei Siamashka
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.cairographics.org/archives/cairo/attachments/20101103/fa2d6f0f/attachment.pgp>

More information about the cairo mailing list