2D Graphics Performance (GDI + vs SlimDX)

I am part of a team that created a tool for viewing and interacting with very large and highly interconnected graphs in C # / WPF. View and interact with the chart using a custom control that accepts a set of DrawingVisuals and displays them on the canvas. Nodes on the chart can have a custom form created using our editor. The current control works very well and is quite compatible with our program, but there are legitimate concerns about performance when considering much larger schedules (20,000+ nodes and many connections).

After a little research, it seems like two approaches:

  • GDI + route where graphics are drawn on WriteableBitmap or InteropBitmap.
  • SlimDX or DirectX option (located in D3DImage)


Given these two extremely different approaches, the route of which is best to consider:

  • Interaction with the schedule should be quick even when viewing the entire schedule.
  • Renewal of visual images should be quick (color or size change)
  • Hit testing should be fast (dot and rectangle).
  • Development must be completed in a timely manner.

Which method would you use and why?

EDIT:
Sounds like a similar question but didn't answer.

+8
c # wpf gdi + slimdx
source share
3 answers

I am using GDI for my mapping application . While GDI + is slower than, say, DirectX, I find that there are many things and tricks that can be used to speed things up. A large amount of processor is used to prepare the data before drawing it, so GDI should not be the only bottleneck.

What you need to look for (and they are general enough to apply other graphic engines):

  • First of all: measure . Use the profiler to find out what the real bottleneck in your code is.
  • Reuse of GDI primitives . It is very important. If you need to draw 100,000 graphic objects that look the same or similar, use the same Pen , Brush , etc. Creating these primitives is expensive.
  • Rendering data cache - for example: do not recalculate the positions of gfx elements if you do not need it.
  • When panning / zooming, draw a scene with lower GDI + quality (and without expensive GDI operations). There are several options for a Graphics object to reduce quality. After the user stops panning, draw a high quality scene.
  • Many, many little things that improve performance. I have been developing this application for 2-3 years (or is it already 4 hmm?), And I still find ways to improve things :). That's why profiling is important - changing the code, and this can affect performance, so you need a new code profile.

One more thing: I did not use SlimDX, but I tried Direct2D (I mean Microsoft.WindowsAPICodePack.DirectX.Direct2D1 ). Performance was significantly faster than GDI + in my case, but I had some problems with rendering bitmaps and never had time to find the right solution.

+7
source share

I recently ported the drawing code to DirectX and was very pleased with the results. Basically, we painted bitmap images using a beat, and we see the visualization time, which can be measured in a few minutes, reduced to 1-2 seconds.

It cannot compare directly with you, as we have switched from a beat in C ++ to Direct3D in C # using SlimDX, but I think you will see the performance benefits, even if they are not orders we see.

I would advise you to take a look at using Direct2D with SlimDX. You will need to use DirectX 10.1, because Direct2D is for some reason not compatible with DirectX 11. If you used the drawing API in WPF, then you will already be familiar with Direct2D, since its API is based on the WPF API, as far as I I can judge. The main problems with Direct2D are the lack of documentation and the fact that it only works in Vista.

I have not experimented with InterX DirectX 10 / WPF, but I believe it is possible (http://stackoverflow.com/questions/1252780/d3dimage-using-dx10)

EDIT: I thought I would give you a comparison with our simple polygon drawing code. First version of WPF:

  StreamGeometry geometry = new StreamGeometry(); using (StreamGeometryContext ctx = geometry.Open()) { foreach (Polygon polygon in mask.Polygons) { bool first = true; foreach (Vector2 p in polygon.Points) { Point point = new Point(pX, pY); if (first) { ctx.BeginFigure(point, true, true); first = false; } else { ctx.LineTo(point, false, false); } } } } 

Now version of Direct2D:

  Texture2D maskTexture = helper.CreateRenderTexture(width, height); RenderTargetProperties props = new RenderTargetProperties { HorizontalDpi = 96, PixelFormat = new PixelFormat(SlimDX.DXGI.Format.Unknown, AlphaMode.Premultiplied), Type = RenderTargetType.Default, Usage = RenderTargetUsage.None, VerticalDpi = 96, }; using (SlimDX.Direct2D.Factory factory = new SlimDX.Direct2D.Factory()) using (SlimDX.DXGI.Surface surface = maskTexture.AsSurface()) using (RenderTarget target = RenderTarget.FromDXGI(factory, surface, props)) using (SlimDX.Direct2D.Brush brush = new SolidColorBrush(target, new SlimDX.Color4(System.Drawing.Color.Red))) using (PathGeometry geometry = new PathGeometry(factory)) using (SimplifiedGeometrySink sink = geometry.Open()) { foreach (Polygon polygon in mask.Polygons) { PointF[] points = new PointF[polygon.Points.Count()]; int i = 0; foreach (Vector2 p in polygon.Points) { points[i++] = new PointF(pX * width, pY * height); } sink.BeginFigure(points[0], FigureBegin.Filled); sink.AddLines(points); sink.EndFigure(FigureEnd.Closed); } sink.Close(); target.BeginDraw(); target.FillGeometry(geometry, brush); target.EndDraw(); } 

As you can see, the Direct2D version works a bit more (and relies on a few helper functions that I wrote), but in fact it is very similar.

+3
source share

Let me try to list the pros and cons of each approach - which may give you some idea of ​​what to use.

GDI Pros

  • Easily draw vector shapes with
  • No need to include additional libraries

Gdi cons

  • Slower than DX
  • It is necessary to limit the "bizarre" drawing (gradients, etc.), or this may slow down the work.
  • If the chart should be interactive - perhaps this is not a great option.

SlimDX Pros

  • Can do some fancy drawing, being faster than GDI
  • If the drawing is interactive, this approach will be MUCH better.
  • Since you draw primitives, you can control quality at every zoom level.

Slimdx cons

  • It's not very easy to draw simple shapes - you need to write your own abstractions or use a library to help you draw shapes.
  • It's not so easy to use GDI, especially if you have not used it before

And maybe I forgot to put more here, but maybe they will do it for a start?

-BUT.

+1
source share

All Articles