[Gtk-sharp-list] Tips for drawing quickly

Aaron Oxford aaron at hardwarehookups.com.au
Tue May 22 08:53:57 EDT 2007


At 10:58 PM 21/05/2007, you wrote:
>I think the situation in Linux is a lot better, or gnome apps would be
>sluggish, and I use them all the time, and I think they are as fast as
>windows apps on the same hardware.
>
>:)

I don't want to start an OS war here, but I just downloaded gnumeric 
for Windows and it was pretty damn slow, almost as slow as my own app.  :-)

And really that is the issue - will it run like a dog on the 'other' 
platform? I'm not surprised that System.Drawing is fastest on its 
native platform, I need to know what is the best compromise for both 
(or all) platforms.

*Sigh* I still need more performance data. Someone else mentioned 
improvements to the speed of recent versions of Cairo. I've checked 
what version of Cairo I'm running and it appears to be 1.0.5000.0, 
not 1.4 which, I read from the release notes is significantly faster 
at certain operations but also marginally slower at other more basic 
operations.

I therefore submit the following very basic, more than likely biased, 
test comparing the three-fold path of fastly drawing under Gtk# - 
purely for interest's sake. Just open the program and resize it, 
keeping it almost the same size but causing it to redraw and gather 
data over a long period. On my machine, (3800 X2, 7600GT, Server2k3, 
Gtk#2.8.3) redrawing overall happens at about 1-2 fps. The measured 
drawing times are:

Gdk:                    324 ms (3 FPS)
Cairo:                  292 ms (3.5 FPS)
System.Drawing: 24 ms (Badooshka)


I'd appreciate some feedback from keen Linux users wanting to show 
off how much better Gnome is than Windows (or how much spankier their 
Core2Duo/2950XT is than my old Athlon). Also, since we mentioned 
performance of different versions and my Cairo seems so far out of 
date, some verification/comparison of results on different versions 
would probably be interesting.

My apologies if there is some Gtk# performance website with a known 
benchmark or something, but I haven't find much even after three days 
of trawling Google and Nabble.

Many thanks in advance,

Aaron.




using System;
using System.Collections;
using Gtk;
using Gdk;
using System.Drawing;

public class Test
{
     private DrawingArea da = null;
     private Gtk.Window wnd;

     long gdkTime = 0;
     long sysTime = 0;
     long cairoTime = 0;

     // Half decent looking context menu.
     public static void Main()
     {
         if (!GLib.Thread.Supported) GLib.Thread.Init();
         Gdk.Threads.Init();
         Gdk.Threads.Enter();

         Application.Init();

         Test t = new Test();

         Application.Run();
         Gdk.Threads.Leave();
     }

     public Test()
     {
         wnd = new Gtk.Window("Test");
         wnd.DefaultSize = new Gdk.Size(400, 300);
         wnd.Destroyed += new EventHandler(wnd_Destroyed);

         da = new DrawingArea();
         da.ExposeEvent += new ExposeEventHandler(da_ExposeEvent);

         wnd.Add(da);
         wnd.ShowAll();
     }

     void da_ExposeEvent(object o, ExposeEventArgs args)
     {
         Gdk.Window window = da.GdkWindow;
         Gdk.Rectangle area = window.FrameExtents;
         area.X = 0;
         area.Y = 0;

         long startTime = DateTime.Now.Ticks;
         Gdk.GC gc = new Gdk.GC(window);

         gc.RgbFgColor = new Gdk.Color(255, 255, 255);
         window.DrawRectangle(gc, true, area);

         Pango.Layout layout = new Pango.Layout(da.PangoContext);

         Gdk.Color gdkBrush = new Gdk.Color(160, 160, 220);
         gc.RgbFgColor = gdkBrush;

         Gdk.GC tgc = da.Style.TextGC(StateType.Normal);

         for (int x = 0; x < 1000; x++)
         {
             layout.SetText("" + x * x);
             window.DrawLayout(tgc, (x * 27) % area.Width, (x * 13) % 
area.Height, layout);
             window.DrawRectangle(gc, true, x * 5 % area.Width, x * 
17 % area.Height, 400, 10);
         }

         long endTime = DateTime.Now.Ticks;

         gdkTime += endTime - startTime;








         startTime = DateTime.Now.Ticks;

         Cairo.Context cairo = CairoHelper.Create(window);

         cairo.ColorRgb = new Cairo.Color(255, 255, 255);
         cairo.Paint();

         Cairo.Color textCol = new Cairo.Color(0, 0, 0);
         Cairo.Color rectCol = new Cairo.Color(160, 160, 220);

         for (int x = 0; x < 1000; x++)
         {
             cairo.ColorRgb = textCol;
             cairo.MoveTo((x * 27) % area.Width, (x * 13) % area.Height);
             cairo.ShowText("" + x * x);

             cairo.ColorRgb = rectCol;
             cairo.Rectangle(x * 5 % area.Width, x * 17 % 
area.Height, 400, 10);
             cairo.Fill();
         }

         endTime = DateTime.Now.Ticks;

         cairoTime += endTime - startTime;




         startTime = DateTime.Now.Ticks;

         Graphics g = Gtk.DotNet.Graphics.FromDrawable(window);
         g.CompositingQuality = 
System.Drawing.Drawing2D.CompositingQuality.HighSpeed;

         g.FillRectangle(new 
SolidBrush(System.Drawing.Color.FromArgb(255, 255, 255)), 0, 0, 
area.Width, area.Height);

         Brush p = new SolidBrush(System.Drawing.Color.FromArgb(0, 0, 0));
         Brush q = new SolidBrush(System.Drawing.Color.FromArgb(160, 
160, 220));
         System.Drawing.Font f = new System.Drawing.Font("", 9);
         for (int x = 0; x < 1000; x++)
         {
             g.DrawString("" + x * x, f, p, (x * 27) % area.Width, (x 
* 13) % area.Height);
             g.FillRectangle(q, x * 5 % area.Width, x * 17 % 
area.Height, 400, 10);
         }

         endTime = DateTime.Now.Ticks;

         sysTime += endTime - startTime;





     }

     void wnd_Destroyed(object sender, EventArgs e)
     {
         showMessage("Gdk " + gdkTime + "       Sys " + sysTime + 
"        Cairo " + cairoTime);
         Application.Quit();
     }

     // This is just so I can pop up a message.
     private void showMessage(string p)
     {
         Gtk.Dialog dlg = new Dialog("caption", wnd, DialogFlags.Modal);
         dlg.AddButton(Gtk.Stock.Ok, Gtk.ResponseType.Ok);
         dlg.DefaultResponse = Gtk.ResponseType.Ok;
         ScrolledWindow sw = new ScrolledWindow();
         Label l = new Label(p);
         l.Wrap = true;
         sw.AddWithViewport(l);
         dlg.VBox.PackStart(sw);
         dlg.SetDefaultSize(320, 160);

         dlg.ShowAll();
         dlg.Run();
         dlg.Destroy();
     }
}




---------------------------------------------------------------------------------
Aaron Oxford   -   aaron+hardwarehookups .com .au
Director, Innovative Computer Solutions (Aust) Pty. Ltd.
49 Maitland Rd, Mayfield, NSW 2304 Australia
http://www.ic-solutions.com.au
Developer, SourceForge project VioLet Composer
http://sourceforge.net/projects/buzz-like



More information about the Gtk-sharp-list mailing list