[Mono-dev] libgdiplus drawing performance

Sebastien Pouliot sebastien.pouliot at gmail.com
Wed May 6 13:48:05 EDT 2009

On Tue, 2009-05-05 at 13:36 -0700, Shade1974 wrote:
> First, let me say, I have been really excited about the mono project and am
> an enthusiast on the grounds that it potentially might allow us to take our
> C# programming multi-platform.  We are developing a C# application that
> needs to draw thousands of separate lines.  I have been having trouble with
> getting drawing to work quickly.  This is one of those unfortunate scenarios
> where it seems almost impossible to Google anything useful, and it took a
> long time before I discovered that you could group thousands of lines
> together into a single drawing path and draw them all at once with a single
> call to the graphics device (GDI+ API).  This is on the order of THOUSANDS
> of times faster, not merely one or two times as fast.  Now, imagine my
> distress after having implemented this blazingly quick drawing in windows
> only to discover that MONO seems to be unable to duplicate this
> optimization.  I believe that the problem originates because the managed
> mono wrapper must take the single DrawPath instruction and sub-divide it
> into the individual calls to the API.  This might be necessary when talking
> to Cairo, but I thought on windows this was simply supposed to forward the
> instructions to GDI+.  The fact that even the windows implementation is slow
> tells me that it's possible that the authors simply didn't know that there
> was a huge performance gain by calling a chunky DrawPath instead of chatty
> individual calls, or else they would at least have supported it in the case
> of windows.

You do realize that this is _all_ open source, right ? That makes it
easy (and faster) to look, instead of speculate, about what the code
actually does (or what the authors knows or not ;-)

Since you did not supply any code it's hard to be sure what could be
causing your problem. I won't speculate besides showing you that your
assumption is wrong since our managed DrawPath is quite simple:

		public void DrawPath (Pen pen, GraphicsPath path)
			if (pen == null)
				throw new ArgumentNullException ("pen");
			if (path == null)
				throw new ArgumentNullException ("path");
			Status status = GDIPlus.GdipDrawPath (nativeObject, pen.nativeObject, path.nativePath);
			GDIPlus.CheckStatus (status);

which in turns calls directly into unmanaged code (so the path is *not*
broken into "chatty" api calls).

                [DllImport ("gdiplus.dll")]
                static internal extern Status GdipDrawPath (IntPtr graphics, IntPtr pen, IntPtr path);

That means that this calls _directly_ on gdiplus.dll (which is MD GDI+
on Windows*). If MS.NET is faster on Windows (than Mono) then the real
performance problem lies elsewhere.

* you'll need to look at libgdiplus source code for other platforms

> Anyway, like I said it took a huge amount of time before I even figured out
> the optimization in the first place and I have just started to work with
> mono.  It's quite probable that I am overlooking something straight forward,
> but I'm having trouble figuring out what it is.  If anyone knows some
> information that could help I'd be grateful.

In general (not graphics or even mono related) if you find a performance
problem please supply a test case that shows the issue*. That will help
people helping you. Otherwise you'll, at best, end up with various
opinions about (in this case) wrong facts - all time consuming for you
(and everyone else wanting to help).


* extra bonus for filling it as a bug report on bugzilla.novell.com so
it does not get lost :)

More information about the Mono-devel-list mailing list