views:

980

answers:

3

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?

+2  A: 

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.

Eamon Nerbonne
I'm currently using this approach: a VirtualPath class that stores the Path data and returns a WPF System.Windows.Shapes.Path as soon as its boundaries are visible.
kitsune
Thanks for pointing me to StreamGeometry, I didn't know this class yet
kitsune
A: 

A brute-force approach might be to implement an ActiveX control and render the graphics directly using Win32. However, this will be somewhat fiddly. QT's canvas control might be a more warm and fluffy approach to the same end and it's noted for rendering this type of thing fairly quickly. Troll provide an ActiveX wrapper for the commercial versions of QT so it might be easier to integate.

ConcernedOfTunbridgeWells
A: 

Hi All!

I bite my head last two days with WPF, trying to get awesome performance for a simplest drawing. Exactly i want to visualize a one polyline with ~800 points. Whatever can be simplest? I use drawingvisual where with drawingcontext use drawingcontext.drawgeometry(streamgeometry) and all this seems to be very slow even on window resize.

My hands are down, i have thoughts that i did a big mistake on decision of my choice what technology to study.

If anyone can give me a right way to get fast drawing with same object complexity, please help. You can save my soul =)

Dmitry