<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<META name=GENERATOR content="MSHTML 8.00.7600.16625"></HEAD>
<BODY>the low performance of cairo_stroke under wine deals to the DIB in 
wine.<BR><A 
href="http://wiki.winehq.org/DIBEngine">http://wiki.winehq.org/DIBEngine</A><BR>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. <BR>To emulate such 
behavior, wine&nbsp;plays memory tricks (by protecting the DIB memory) and 
switch between a<FONT color=#ff0000> 'GDI mode' and 'memory mode'</FONT>. <BR>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. <BR><BR>This explains the 
low performance of cairo_stroke under wine.<BR>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.<BR>1.copy the content from the screen to the DIB <FONT 
color=#ff0000>(GDI mode)<BR></FONT>if ((surface-&gt;flags &amp; 
CAIRO_WIN32_SURFACE_CAN_BITBLT) &amp;&amp;<BR>&nbsp;&nbsp;&nbsp; &nbsp;BitBlt 
(local-&gt;dc,<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;0, 0,<BR>&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;width, height,<BR>&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;surface-&gt;dc,<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;x, 
y,<BR>&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;SRCCOPY))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
{<BR>&nbsp;&nbsp;&nbsp; &nbsp;status = 
CAIRO_STATUS_SUCCESS;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>2. 
handle the DIB by accessing the memory <FONT color=#ff0000>(memory 
mode)<BR><BR></FONT>static void<BR>sse2_composite_over_n_8_8888 
(pixman_implementation_t 
*imp,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
pixman_op_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
op,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
pixman_image_t *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
src_image,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
pixman_image_t *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
mask_image,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
pixman_image_t *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
dst_image,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
int32_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
src_x,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
int32_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
src_y,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
int32_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
mask_x,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
int32_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
mask_y,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
int32_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
dest_x,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
int32_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
dest_y,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
int32_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
width,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
int32_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
height)<BR><BR>3.copy the content from DIB back to the screen<BR>BitBlt 
(surface-&gt;dc,<BR>&nbsp;&nbsp; image_rect-&gt;x, 
image_rect-&gt;y,<BR>&nbsp;&nbsp; image_rect-&gt;width, 
image_rect-&gt;height,<BR>&nbsp;&nbsp; local-&gt;dc,<BR>&nbsp;&nbsp; 0, 
0,<BR>&nbsp;&nbsp; SRCCOPY))<BR><BR>IF we have entered the gdi mode, then 
setting only one pixel in the memory mode will take several ms.<BR>Thus the 
performance is very low.<BR>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.<BR><BR>how to avoid switching between a<FONT color=#ff0000> 'GDI mode' and 
'memory mode'?<BR></FONT><BR>oken<BR><BR>2010/9/27 oken 
&lt;okenjian@163.com&gt;: <BR>&gt; Hi, all, <BR>&gt; I am using cairo 1.8.10 
under wine, and i find that in some situations, <BR>&gt; cairo_stroke works very 
slow. <BR>&gt; drawing 1000 lines on an image surface takes only 915ms, but on a 
Win32 <BR>&gt; surface it takes 10,493ms! <BR>&gt; the testing code is as 
follow: <BR><BR>This is also what I see in my app (mostly scrolling text), the 
<BR>framerate using an image surface is much higher. <BR><BR>&gt; I run my test 
under both wine and win7, and i get the similar result:drawing <BR>&gt; on an 
image surface is much faster than WIN32 surface does. <BR>&gt; Most of the time 
is consumed by cairo_stroke. <BR>&gt; I know i can move cairo_stroke out of the 
for loop and call it only once, it <BR>&gt; improve the performance a lot. 
<BR><BR>The win32 surface is really basic, since it uses the windows GDI 
<BR>subsystem. Pixman has a lot of fast paths using e.g. SSE2 assembly, 
<BR>which makes the image surface quite fast. <BR><BR>&gt; I also find that 
drawing rectangles on a win32 surface is fast if the <BR>&gt; parameters are 
integer, however using double decrease the performance a <BR>&gt; lot(about 10 
times slower!). <BR><BR>By double do you mean, non-integer doubles? That is 
expected, because <BR>the rectangles are not pixel-aligned. <BR><BR>&gt; I have 
a few questions: <BR>&gt; 1. does it make sense that drawing a single line(not 
horizontal or vertical) <BR>&gt; or a rectangle(with double parameters) on a 
WIN32 surface takes about 10ms? <BR><BR>I guess so. <BR><BR>&gt; 2. is it 
possible to improve it ? how? <BR><BR>Render all your lines to an image surface 
and when you're done, blit <BR>the pixels to the win32 surface. <BR><BR>&gt; 3. 
what can i do the improve the performance of cairo if i am using it under 
<BR>&gt; wine? <BR>&gt; <BR>&gt; thanks! <BR><BR>Maarten <BR>. 
<BR><BR><BR></BODY></HTML>