[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).
Sebastien
* 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