2D Drawing Performance (GDI+ vs SlimDX)

CBent picture CBent · Apr 23, 2012 · Viewed 13.8k times · Source

I am part of a team that has created a tool to view and interact with very large and heavily interconnected graphs in C#/WPF. Viewing and interacting with the graph is done through a custom control that takes in a set of DrawingVisuals and displays them on a canvas. Nodes in the graph may have a custom shape created with our editor. The current control works very well and is fairly coupled with our program but there are legitimate worries about performance when considering much larger graphs (20,000+ nodes and lots of connection).

After doing a bit of research it seems the two approaches are:

  • A GDI+ route where graphics are drawn to a WriteableBitmap or InteropBitmap.
  • SlimDX or DirectX variant (hosted in a D3DImage)


Given these two extremely different approaches which route would be best to take considering:

  • Interacting with the graph must be fast even while viewing the whole graph.
  • Updating the visuals should be fast (color or size change)
  • Hit testing must be fast (point and rectangle).
  • Development must be completed in a timely manner.

Which method would you use and why?

EDIT:
It looks like a similar question was asked but not answered.

Answer

Igor Brejc picture Igor Brejc · Apr 25, 2012

I use GDI for my cartographic application. While GDI+ is slower than, say, DirectX, I find that there are a lot of things and tricks that can be used to speed things up. A lot of CPU is used for preparing the data before drawing it itself, so GDI should not be the only bottleneck there.

Things to look out for (and these are general enough to apply to other graphics engines, too):

  1. First of all: measure. Use a profiler to see what is the real bottleneck in your code.
  2. Reuse GDI primitives. This is vital. If you have to draw 100,000 graphics objects that look the same or similar, use the same Pen, Brush etc. Creating these primitives is expensive.
  3. Cache the rendering data - for example: don't recalculate gfx element positions if you don't need to.
  4. When panning/zooming, draw the scene with lower GDI+ quality (and without expensive GDI operations). There are a number of Graphics object settings to lower the quality. After the user stops panning, draw the scene with the high quality.
  5. A lot and lot of little things that improve performance. I've been developing this app for 2-3 years (or is it 4 already hmm?) now and I still find ways to improve things :). This is why profiling is important - the code changes and this can affect the performance, so you need to profile the new code.

One other thing: I haven't used SlimDX, but I did try Direct2D (I'm referring to Microsoft.WindowsAPICodePack.DirectX.Direct2D1). The performance was considerably faster than GDI+ in my case, but I had some issues with rendering bitmaps and never had the time to find the proper solution.