23

I am creating a WPF mapping program which will potentially load and draw hundreds of files to the screen at any one time, and a user may want to zoom and pan this display. Some of these file types may contain thousands of points, which would most likely be connected as some kind of path. Other supported formats will include TIFF files.

Is it better for performance to have a single DrawingVisual to which all data is drawn, or should I be creating a new DrawingVisual for each file loaded?

If anyone can offer any advice on this it would be much appreciated.

Greg
  • 1,673
  • 4
  • 20
  • 27
  • 2
    This sounds related, although maybe not quite what you want: [Microsoft Deep Zoom](http://msdn.microsoft.com/en-us/library/cc645050(v=vs.95).aspx) – Ray Jan 03 '12 at 14:39

2 Answers2

42

You will find lots of related questions on Stack Overflow, however not all of them mention that one of the most high-performance ways to draw large amounts of data to the screen is to use the WriteableBitmap API. I suggest taking a look at the WriteableBitmapEx open source project on codeplex. Disclosure, I have contributed to this once, but it is not my library.

Having experimented with DrawingVisual, StreamGeometry, OnRender, Canvas, all these fall over once you have to draw 1,000+ or more "objects" to the screen. There are techniques that deal with the virtualization of a canvas (there' a million items demo with Virtualized Canvas) but even this is limited to the ~1000 visible at one time before slow down. WriteableBitmap allows you to access a bitmap directly and draw on that (oldskool style) meaning you can draw tens of thousands of objects at speed. You are free to implement your own optimisations (multi-threading, level of detail) but do note you don't get much frills with that API. You literally are doing the work yourself.

There is one caveat though. While WPF uses the CPU for tesselation / GPU for rendering, WriteableBitmap will use CPU for everything. Therefore the fill-rate (number of pixels rendered per frame) becomes the bottleneck depending on your CPU power.

Failing that if you really need high-performance rendering, I'd suggest taking a look at SharpDX (Managed DirectX) and the interop with WPF. This will give you the highest performance as it will directly use the GPU.

Anton Menshov
  • 2,266
  • 14
  • 34
  • 55
Dr. Andrew Burnett-Thompson
  • 20,980
  • 8
  • 88
  • 178
  • Thanks, this is interesting. I would prefer to use the WPF graphics if possible though, as I have previously created GIS programs using GDI+ and I would prefer now to try something that is making use of the GPU. When you say "objects", do you mean Visual objects, or would say several lines in a single Visual count as several objects? – Greg Jan 03 '12 at 16:51
  • Hi Greg, when I said objects I meant rendered items, whether they be drawn by GDI, or WPF visuals etc... Regarding wpf's GPU acceleration, all that performance boost and more is lost by CPU side layout and tesselation. Please see my website here http://goo.gl/1nCpw for a demonstration of what a bitmap approach can do, and compare to other similar components here http://goo.gl/ohLFj achieve with the wpf rendering primitives. – Dr. Andrew Burnett-Thompson Jan 03 '12 at 17:59
  • Here's [a question](http://stackoverflow.com/questions/22599806/speeding-up-an-l-system-renderer-in-c-wpf/22727519?noredirect=1#comment34646163_22727519) where WriteableBitmapEx made things much faster. – dharmatech Mar 29 '14 at 17:45
  • It really would be nice to have something with the performance and capabilities of the HTML5 Canvas. WPF definitely has the capabilities, but the performance breaks down eventually. – dharmatech Mar 29 '14 at 17:47
  • @Dr.ABT have you solved the line thickness issue of WritablebitmapEx ? Is saw your post here : http://nokola.com/blog/post/2010/10/14/Anti-aliased-Lines-And-Optimizing-Code-for-Windows-Phone-7e28093First-Look.aspx#disqus_thread – eran otzap Jun 29 '14 at 16:59
  • Yeah I did - basically rendered an Ellipse using WPF's RenderTargetBitmap to a bitmap of size NxN, then performed an alpha-blended blit of the ellipse at every point of a Bresenham line. It doesn't produce super smooth lines - slightly jagged actually due to the integer coordinate nature of WriteableBitmapEx, but quite fast! – Dr. Andrew Burnett-Thompson Jun 30 '14 at 06:37
  • Thanks for the links. The "million items demo" is a bomb! – alex555 Mar 22 '17 at 11:16
10

Using many small DrawingVisuals with few details rendered per visual gave better performance in my experience compared to less DrawingVisuals with more details rendered per visual. I also found that deleting all of the visuals and rendering new visuals was faster than reusing existing visuals when a redraw was required. Breaking each map into a number of visuals may help performance.

As with anything performance related, conducting timing tests with your own scenarios is the best way to be sure.

Doug Ferguson
  • 2,538
  • 2
  • 16
  • 23