[Mono-winforms-list] MWF painting VERY slow compared to .NET

Peter De Jager peterdj at telkomsa.net
Thu Jul 28 16:46:46 EDT 2005


I'm attaching a small code snippet. You *should* use Invoke() instead of
painting to a Form directly, but in this (very simple) example, no other
thread is painting to the form so it should be safe.

You can compile with .NET or mcs. Put an image file, "Image.png", in the
same directory as the executable before running it. The image should be
smaller than approx. 800x600 otherwise it will be clipped. When the form is
displayed, it shows nothing (not even a background, except on Mono where the
background is incorrectly painted). When you click on the form, it
repeatedly paints the bitmap to the form and displays the mean frame rate
over a 10 second period. On my hardware (and using my "Image.png"), the
figures at the end of the 10 seconds are 162 for .NET and 7.65 for Mono.

With regards to Mac, I know very little about X11 (as with Linux). To be
honest, I don't even understand your question ;-). When trying to get MWF
and gtk-sharp running I saw on the mailing lists that X11 needs to be
installed, so I did that. I also tried to run 'mono.exe' from an X11
terminal (I don't know how this differs from a normal terminal on Mac).
After macpack I've managed to get a MWF app displaying for an instant before
quitting, so my success has been limited so far. However, all of my non-gui
code is running without problems under Mono on OS X, albeit at approximately
half the speed of Mono on Linux (FC 4), on the same PowerPC hardware.

Pete.
 

> -----Original Message-----
> From: Peter Dennis Bartok [mailto:peter at novonyx.com] 
> Sent: Thursday, July 28, 2005 20:25
> To: Peter De Jager; 'Miguel de Icaza'
> Cc: mono-winforms-list at lists.ximian.com
> Subject: Re: [Mono-winforms-list] MWF painting VERY slow 
> compared to .NET
> 
> Peter,
> 
> I am curious as to how you tested performance/framerate. Any 
> chance you could provide the code? (Binary should be ok, 
> doesn't have to be source yet). I'd love to go through and 
> see where we spend the cycles. (And I will also test with our 
> MWF but Microsoft's GDI+ on Win32, which will give an idea of 
> how much impact our managed approach to drawing controls has)
> 
> When Jackson worked on improving performance of the X11 
> driver's event loop, he went through the Gtk+ code, so I'd 
> assume he modeled it after theirs and we should have the same 
> benefits.
> 
> Also, you mention OS X. Are you testing with the X11 driver 
> or with the OS X driver?
> 
> Also, so far we have spent little time optimizing things, 
> we've only tried to get to a code-complete state, but we're 
> reaching the point where we're looking into performance, so 
> you picked the perfect time to bring up the issue :-)
> 
> Cheers,
>   Peter
> 
> -----Original Message-----
> From: "Peter De Jager" <peterdj at telkomsa.net>
> To: "'Miguel de Icaza'" <miguel at ximian.com>
> Cc: <mono-winforms-list at lists.ximian.com>
> Date: 28 July, 2005 12:08
> Subject: RE: [Mono-winforms-list] MWF painting VERY slow 
> compared to .NET
> 
> 
> >That would make sense. It almost appears as if the MWF event loop is 
> >clocked at a fixed frequency, resulting in the (almost) fixed frame 
> >rate regardless of architecture or video drivers. Of course 
> it will be 
> >more complex than that, but it does appear that the delay is 
> at least 
> >in part due to the event loop.
> >
> >What would be the best way to proceed though? In the last few days I 
> >have tried gtk-sharp on Mac without much success, having had 
> a lot of 
> >trouble installing gtk-sharp under PowerPC (at least with Mono 1.1.8 
> >and FC4). I saw the post by Attila Balogh who provides a 
> modified Mono 
> >framework for OS X Tiger (90MB), which includes gtk-sharp 
> 1.0.10, but I 
> >haven't tried it yet.
> >I
> >thought I'd hold out for a while and keep testing on Linux 
> (Intel/PPC) 
> >using MWF. I've also had a look at wx.Net but it appears 
> that gtk-sharp 
> >is more widely supported. In a perfect world I would use MWF 
> since this 
> >requires no change from my .NET code, but failing that, I 
> was hoping to 
> >use a single GUI toolkit for both Linux and OS X. Does gtk-sharp fit 
> >the bill?
> >
> >Pete.
> >
> >
> >> -----Original Message-----
> >> From: Miguel de Icaza [mailto:miguel at ximian.com]
> >> Sent: Thursday, July 28, 2005 19:32
> >> To: vlindos at nucleusys.com
> >> Cc: Peter De Jager; mono-winforms-list at lists.ximian.com
> >> Subject: Re: [Mono-winforms-list] MWF painting VERY slow 
> compared to 
> >> .NET
> >>
> >> Hello,
> >>
> >> > Slowness of MWF drawing comes from Cairo. MWF uses 
> libgdiplus for 
> >> > drawing, libgdiplus uses cairo/libpixmain backends for 
> drawing and 
> >> > uses version 0.3.0 of Cairo. Currently Cairo is version 
> 0.5.2. The 
> >> > problem is that Cairo isn't yet stable project as API is
> >> changed even
> >> > on minor version change. On mailing lists of Cairo there 
> is talk of 
> >> > soon releasing of version 1 which means freezing the API.
> >> But 'soon'
> >> > could be month or year by my opinion.
> >>
> >> Although Cairo is known to be a part of the problem, 
> another part of 
> >> the equation might be the event loop processing.
> >>
> >> I do not remember the details, but Gtk+ spent quite a bit of time 
> >> dealing with improving their main loop and event processing to 
> >> improve performance.
> >>
> >> Miguel.
> >>
> >
> >_______________________________________________
> >Mono-winforms-list maillist  -  Mono-winforms-list at lists.ximian.com
> >http://lists.ximian.com/mailman/listinfo/mono-winforms-list
> >
> > 
> 
> 
-------------- next part --------------
using System;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;

class Test {

	static TestForm testForm = new TestForm();

	static void Main() {
		Application.Run(testForm);
	}

	class TestForm : Form {

		public TestForm() {
			Text = "Paint Test";
			Size = new Size(800, 600);
			StartPosition = FormStartPosition.CenterScreen;
		}

		protected override void OnPaintBackground(PaintEventArgs e) { }

		protected override void OnMouseDown(MouseEventArgs e) {
			new Thread(new ThreadStart(PaintTest)).Start();
		}
	}

	public static void PaintTest() {

		// setup
		string currentPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName);
		Bitmap image = new Bitmap(Path.GetFullPath(currentPath + Path.DirectorySeparatorChar + "Image.png"));
		Bitmap canvas = new Bitmap(image);
		Font font = new Font(FontFamily.GenericMonospace, 12);

		// test
		int frames = 0;
		DateTime start = DateTime.Now;
		using (Graphics gScreen = testForm.CreateGraphics()) {
			using (Graphics gCanvas = Graphics.FromImage(canvas)) {

				// for 10 seconds...
				while (DateTime.Now.Subtract(start) < new TimeSpan(0, 0, 10)) {

					// paint image
					gCanvas.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height), new Rectangle(0, 0, image.Width, image.Height), GraphicsUnit.Pixel);

					// write framerate
					++frames;
					if (DateTime.Now.Subtract(start).TotalSeconds > 0) {
						double fps = frames / DateTime.Now.Subtract(start).TotalSeconds;
						gCanvas.FillRectangle(new SolidBrush(Color.White), 0, 0, image.Width, 32);
						gCanvas.DrawString(string.Format("Fps: {0}", Math.Round(fps, 2)), font, Brushes.Black, new Point(4, 4));
					}

					// display
					gScreen.DrawImage(canvas, new Rectangle(0, 0, canvas.Width, canvas.Height), new Rectangle(0, 0, canvas.Width, canvas.Height), GraphicsUnit.Pixel);
				}
			}
		}
	}
}


More information about the Mono-winforms-list mailing list