Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Performance: Displaying thousands of Paths / Shapes on a Canvas

I'm currently developing a visualization tool that draws WPF shapes such as paths, ellipses etc. on a Canvas. I've already implemented a virtualized approach where Shapes are being destroyed and created on the fly depending on their visibility. However, even with only like 600 ellipses visible, the application seems to struggle.

What are my options to speed things up? I'm thinking rendering grouped Shapes (let's say 500 at a time) as transparent bitmaps and only painting these on the Canvas. But I don't know whether that's a good idea... From what I gather this requires some sort of hack, if transformations were applied:

     VisualBrush shapeBrush = new VisualBrush(shape);  

     DrawingVisual drawingVisual = new DrawingVisual();  
     DrawingContext drawingContext = drawingVisual.RenderOpen();  

     using (drawingContext)  
     {  
        drawingContext.DrawRectangle(shapeBrush, null, new Rect(new Point(0, 0), new Point(actualWidth, actualHeight)));  
     }  
     renderTarget.Render(drawingVisual);  

What about using a big WritableBitmap? Would that be another approach?

like image 992
kitsune Avatar asked Sep 29 '09 07:09

kitsune


2 Answers

WPF under the covers works with drawings and geometries - when you say you're working with shapes, are these actual UIElements? Such elements are quite a bit more heavy-weight. If you use just basic (preferably stream-) geometries to draw drawings, you'll get the best performance in my experience.

I managed to get up to around 10000 dots with a reasonable framerate with that approach, but anything more complex than a dot starts slowing things down (say, round dots or even just rectangles). Still, basic geometries and basic drawings are the way to go if you want to avoid as much WPF overhead as possible.

A Writeable bitmap is clearly eventually faster, but that means rending all those shapes yourself, or, caching the result bitmap if it's mostly static. Also, you'll generally want to apply transformations before rendering to bitmap rather than applying them to the rendered bitmap itself.

like image 74
Eamon Nerbonne Avatar answered Nov 10 '22 14:11

Eamon Nerbonne


I'm aware this is an old question, I'm just answering in the interest of the community.

I researched the topic a bit, and the best I've found is to manually create DrawingVisuals like you say. It saves a lot of internal work to WPF, so it ends up being a lot faster. I used the technique to create a lightweight chart that can have couple hundred points. Here's the article I inspired myself from, you might already know about it.

http://blogs.microsoft.co.il/blogs/tamir/archive/2008/03/02/how-to-high-performance-graphics-in-wpf.aspx

EDIT: New URL http://khason.net/blog/how-to-high-performance-graphics-in-wpf/
EDIT: Newer URL: http://dedjo.blogspot.com/2008/03/how-to-high-performance-graphics-in-wpf.html

Good luck.

like image 40
Djof Avatar answered Nov 10 '22 16:11

Djof