[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:

1. CAIRO_FORMAT_RGB24

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).

2. CAIRO_FORMAT_ARGB32

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.

3. CAIRO_FORMAT_RGB16_565

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