[cairo] about cairo_stroke's performance
okenjian at 163.com
Wed Oct 13 07:55:08 PDT 2010
the low performance of cairo_stroke under wine deals to the DIB in wine.
In the Win32 API, an application can draw in a DIB via GDI calls or via direct memory access without any synchronization calls in between.
To emulate such behavior, wine plays memory tricks (by protecting the DIB memory) and switch between a 'GDI mode' and 'memory mode'.
On each of these transitions, we have to copy the DIB to/from the X server. It works, but it is slow, especially over the network.
This explains the low performance of cairo_stroke under wine.
Drawing a line from (0,0) to (500, 500) on a screen, it takes 10ms, I find it that the following 3 functions are called.
1.copy the content from the screen to the DIB (GDI mode)
if ((surface->flags & CAIRO_WIN32_SURFACE_CAN_BITBLT) &&
status = CAIRO_STATUS_SUCCESS;
2. handle the DIB by accessing the memory (memory mode)
sse2_composite_over_n_8_8888 (pixman_implementation_t *imp,
pixman_image_t * src_image,
pixman_image_t * mask_image,
pixman_image_t * dst_image,
3.copy the content from DIB back to the screen
IF we have entered the gdi mode, then setting only one pixel in the memory mode will take several ms.
Thus the performance is very low.
I try to remove the first step, the performance is 3 times faster, but of cause, the result is not right without the first step.
how to avoid switching between a 'GDI mode' and 'memory mode'?
2010/9/27 oken <okenjian at 163.com>:
> Hi, all,
> I am using cairo 1.8.10 under wine, and i find that in some situations,
> cairo_stroke works very slow.
> drawing 1000 lines on an image surface takes only 915ms, but on a Win32
> surface it takes 10,493ms!
> the testing code is as follow:
This is also what I see in my app (mostly scrolling text), the
framerate using an image surface is much higher.
> I run my test under both wine and win7, and i get the similar result:drawing
> on an image surface is much faster than WIN32 surface does.
> Most of the time is consumed by cairo_stroke.
> I know i can move cairo_stroke out of the for loop and call it only once, it
> improve the performance a lot.
The win32 surface is really basic, since it uses the windows GDI
subsystem. Pixman has a lot of fast paths using e.g. SSE2 assembly,
which makes the image surface quite fast.
> I also find that drawing rectangles on a win32 surface is fast if the
> parameters are integer, however using double decrease the performance a
> lot(about 10 times slower!).
By double do you mean, non-integer doubles? That is expected, because
the rectangles are not pixel-aligned.
> I have a few questions:
> 1. does it make sense that drawing a single line(not horizontal or vertical)
> or a rectangle(with double parameters) on a WIN32 surface takes about 10ms?
I guess so.
> 2. is it possible to improve it ? how?
Render all your lines to an image surface and when you're done, blit
the pixels to the win32 surface.
> 3. what can i do the improve the performance of cairo if i am using it under
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the cairo