[Mono-dev] libgdiplus drawing performance

oken okenjian at 163.com
Mon Sep 27 08:57:43 EDT 2010

On Sun, 2010-09-26 at 01:33 -0700, oken wrote: 

> #define VS(fun) \ 
> do{\ 
> GpStatus status = fun; \ 
> if (Ok != status) \ 
> {\ 
> assert(!"invalid status");\ 
> return status;\ 
> }\ 
> }while(0) 
> int width = 1000; 
> int height = 1000; 
> GpStatus status = Ok; 
> BYTE *scan0 = NULL; 
> VS(GdipCreateBitmapFromScan0(width, height, width * 4, 
> PixelFormat32bppARGB, scan0, &m_bmp)); 
> VS(GdipGetImageGraphicsContext(m_bmp, &m_pGraphics)); 
> VS(GdipGraphicsClear(m_pGraphics, 0xffffffff)); 
> VS(GdipCreatePen1(0xa0f0a000, (REAL)2.0, UnitPixel, &m_pPen)); 
> VS(GdipCreateSolidFill(0xa00000ff, &m_pSolidBrush)); 
> VS(GdipSetPenColor(m_pPen, 0xff0000ff)); 
> for (int i = 0; i < nTimes ; i++) 
> { 
> VS(GdipDrawLine(m_pGraphics, m_pPen, 100, 100, 500, 500)); 
> } 
> I also find that libgdiplus's performance is slow. 

libgdiplus main goal is compatibility, it's an extra layer on top of 
cairo and will never be a racing horse. OTOH your contributions to help 
performance, without hurting compatibility, is welcome. 

> In my example, drawing 1000 lines takes me 5,000ms! 
> I find it that most of the time is consumed by "cairo_stroke" in 
> stroke_graphics_with_pen (GpGraphics *graphics, GpPen *pen). 
> I am calling libgdiplus's API under wine! 
> How to improve the performance? 

Does not wine ship its own libgdiplus ? If you're using their version 
then you should ask them about their performance advice. 

If you're using Mono's libgdiplus then make sure you're using the latest 
(not the embedded) cairo. That will bring you all the performance work 
done by the cairo folks since cairo 1.6. 


Yes, I am using the latest cairo(1.8.10). It works faster than the embedded one. But not as I expect.
It's very slow to draw lines on a WIN32 surface.

In my experience, tips to improve the performance of libgdiplus:
1. using the following method to modify GpStatus cairo_SetGraphicsClip (GpGraphics *graphics) which is in graphics-cairo.c, or cairo_clip is very slow.
" The trick to get fast clipping is to ensure the path is always aligned with integer positions on the device-pixel grid. And the easiest way to do that is to use an identity transformation, (cairo_identity_matrix), and construct the path by calling cairo_rectangle with integer values."
2.do not use antialias whenever possible
for example, GpStatus status = gdip_plot_path (graphics, path, TRUE); in cairo_FillPath should change TRUE to FALSE
3.Do not stroke whenever possible
for example, GpStatus status = fill_graphics_with_brush (graphics, brush, TRUE); in cairo_FillPath should change TRUE to FALSE

They help improve the performance a lot, at lease in my test cases!

Mono-devel-list mailing list 
[hidden email] 

View message @ http://mono.1490590.n4.nabble.com/libgdiplus-drawing-performance-tp1537623p2715324.html 
To unsubscribe from libgdiplus drawing performance, click here. 
View this message in context: http://mono.1490590.n4.nabble.com/libgdiplus-drawing-performance-tp1537623p2715378.html
Sent from the Mono - Dev mailing list archive at Nabble.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20100927/0adcc5ec/attachment-0001.html 

More information about the Mono-devel-list mailing list