EndDraw() takes 80 % of working time in Direct2D - c#

I face one critical Performance problem in my Direct2D application. I make use of Direct2D to draw my graph using PathGeometry to get better performance and to achieve the clean rendering in Windows 8.1.
While creating the DeviceResources, i create the PathGeometry using the Factory interface. Then i set the Graph points to draw my graph in the output surface. Finally rendered ImageSource will be used as the source for my Image element in the XAML.
I just followed the below sample link to achieve my scenario.
http://code.msdn.microsoft.com/windowsapps/XAML-SurfaceImageSource-58f7e4d5
The above sample helped me a lot to get the ImageSource output from the Direct2D and finally used across the XAML/C# app.
Lets come to my problem. I use more than 24 graphs in the single Page of my Windows Store application. This graph allows the user to manipulate in Left and Right position and also allows to scale to the particular zoom level.
Hence whenever user tries to manipulate the graph , i just set the Translation and Scaling matrix to the TransformedPathGeometry instead of creating the new one for each and every time.
ID2D1TransformedGeometry *m_pTransformedGeometry;
pFactory->CreateTransformedGeometry(graphgeometry, combinedMatrix, &m_pTransformedGeometry);
Finally i draw the TransformedGeometry using the DrawGeometry method.
I checked my application using the Performance analysis tool in the VisualStudio2013. I could see that in the particular peek level, It takes more than 80% of running time to call the m_d2deviceContext->EndDraw() method. I attached the below screen shot to get more idea in this performance output.
Is there any way to increase this performance considerably ?
Could you please anyone help me in this ?
Regards,
David C

THere is a difference between slow performance and time spend.
If your draw method does more work than other parts, can mean that this method is slow but it also can mean that your other parts don't need a lot of cpu.
88.2% tells you only that you spend more time drawing that stuff than doing other stuff.
Use an timer to determine if your draw is slow.

"i just set the Translation and Scaling matrix to the
TransformedPathGeometry instead of creating the new one for each and
every time."
I hope you use world transform? Else you overwrite the pointer without releasing it before, providing a memory leak. You cannot change the matrix of a geometry directly, you have to recreate it each time, or if you can, you apply the transform to the entire world.

Related

Post-processing screen image before rendering it on display

I'm working on a tinny software (C# and WPF) that does some filtering to the screen output. Examples on the filtering I'm talking about:
Customizable blue light filtering.
Increase/Decrease screen brightness (via changing the colors, not actual brightness)
Inverting screen colors.
And some more, but the simple idea is to tweak the pixel values of the screen after everything else is done rendering, but before showing the result.
Q1: How can I actually access (and then edit) the screen image/frame?
I've heard of getting and editing the screen DC directly (Win32) but I don't know if it's a good way, nor how to do it exactly.
Q2: what is the best way of applying these filters?
I think that tweaking every single pixel individually is a really bad way of doing it. (My code runs on the CPU and this process needs to be done every frame!)
Q3: Is there an event or hook for when windows is refreshing/updating the screen?
If yes, how can I register this process to it?
Note: I want a really performant way so that I don't lose any frame rate if possible.
Note: My preferred language for this is C#, C++ is ok.
Thanks a ton.

How much improvement can I expect with SharpDX over heavily optimized GDI code in C#/WinForms?

I've been working on a C#/GDI graphical app for a couple years. I've spent a lot of time optimizing the drawing code. I am drawing to the screen by invalidating a PictureBox control about 10 times a second, and by leveraging subsequent OnPaint event that occurs when Windows triggers it. The OnPaint event gives me access to the Graphics object via the PaintEventArgs param.
Per frame: I draw hundreds of lines, hundreds of rectangles, and I call the Graphics.DrawString() method hundreds of times as well.
I started putting together a SharpDX project in hopes I could draw more 2D elements, and draw faster to the screen. I set up 2 test projects that draw the same 2D elements on the screen using GDI and using SharpDX. I used a C# StopWatch object to detect how long it was taking to draw all the 2D elements. So far, I have not noticed any speed improvement when drawing with SharpDX. Both GDI and SharpDX average about 20millis per draw.
How much of a speed improvement should I expect by using SharpDX? And which portion of the rasterization is supposed to make it faster than GDI?
I worked on a Windows Forms app where the "rendering system" was pluggable, and I initially wrote two rendering systems: one in GDI+, and one in Managed DirectX (a .NET wrapper around DirectX, similar to SharpDX). Because I was doing a lot of drawing of images at arbitrary scales, Managed DirectX blew GDI+ out of the water for our use case. Drawing code that used 1-pixel-wide lines was also very fast in Managed DirectX. Thick lines were much slower than single-pixel lines, because they were actually rendered as triangle strips (which can be drawn quickly by the GPU) whose coordinates had to be calculated by the CPU, and the geometry was complicated by segment joints (which were rounded, if I remember right). Fortunately, in our application we didn't need to draw curves, but those would have to be approximated by small line segments (for single-pixel widths) and triangles (for anything thicker).
It's things like CPU-based approximation and triangulation that slow a Direct3D app down. 3D games use pre-calculated meshes and make use of vertex buffers on the GPU to avoid moving data back and forth from the CPU to GPU. I don't have any data comparing speeds between GDI+ and DirectX, but these are some things to consider.
Direct2D takes a bit of getting used to, but once you get it up and running properly I can promise that you will never look back. I used it to migrate a very large project which was based on DirectDraw with GDI+ Interop and saw a huge performance increase as well as better stability and a more satisfying development experience.
It has received a lot of negative press about performance, particularly when it was first introduced but if you hook it up to a DXGI swap chain (which is very easy to do) and keep your code sensible, the benefits will be most clear.
SharpDX is the right choice and it will only get faster in the near future, with SSE/SIMD driven primitives just around the corner.

WPF Fastdrawing for Audio visualation

As part of my audio libary i would like to create a sample visualisations.
I know how I get the values I want to draw like fft results and so on.
But the main problem is that I don t know whats the best way to draw them. I have quite a lot of experience in using wpf but I never had to do something like this. What should I use to keep performance as good as possible?
There are a number of different approaches you can take, depending on the quality you need, memory usage, and performance....here are just some.
create a new object derived from FrameworkElement, and then inside draw the "visual" aspect dynamically by drawing onto a DrawingContext during OnRender. Drawings have a much lower overhead than other WPF elements such as Shapes, Image, etc. However, it still may not scale well if you have 1000s of elements. http://msdn.microsoft.com/en-us/library/ms751619.aspx
WriteableBitmapEx....it will give you the drawing primitives you need to write into a Bitmap directly. http://writeablebitmapex.codeplex.com/ .. see this for some demos which are spookily similar to what you would do for an audio visualization. http://blogs.claritycon.com/blog/2011/03/advanced-animation-animating-15000-visuals-in-silverlight-2/
use DirectX with Direct2D. This offers DirectX like performance, but you would need to use COM interop or C++/CLI code wrappers to make it available to your .NET C# code. http://www.codeproject.com/Articles/113991/Using-Direct2D-with-WPF
Some other links:
http://jeremiahmorrill.wordpress.com/2011/02/14/a-critical-deep-dive-into-the-wpf-rendering-system/

Native WPF vs. Custom DirectX for displaying large images

I need to speed up my image viewer, and wondering if I should be looking into creating my own DirectX control to do so.
My image viewer displays medical images. They can be pretty large. We're talking 55mb when it comes to mammography. The pixel data is 16bit greyscale stored in a ushort array. Without getting into the gory details, my current approach is loading the pixel data into an ImageSource, and using the WPF Image control.
I've never done anything with DirectX. Is it worth diving into it? Would it be any faster than the native WPF stuff? If so how significantly? Or, should I just forget about DirectX and look into areas where I can improve my current approach?
Before somebody says so, I know WPF utilize DirectX. I'm wondering If removing the WPF layer and writing the DirectX myself will improve performance.
I have some experience drawing multi-gigabyte satellite and chart imagery. Working with imagery around 55MB should probably work okay even without trying to optimize it too much. You haven't really given enough detail to recommend one alternative over the other, so I will give my opinion on the pros and cons.
Using 2D windows APIs will be the simplest to implement and should always be fast enough if you don't need to rotate and simply want to display an image and zoom and pan around. If you treat it as one large image the performance will not be as good when you zoom out if you are drawing with halftoning to give a nice smooth image. This is because it will effectively have to read all 55mb of image every time it draws.
To get around this performance issue you can make multiple bitmaps, effectively mip-mapping your image. As you zoom out you can pick the reduced resolution image closest to the resolution you are trying to draw . If you are not familiar with mip-mapping here is a Wikipedia link:
http://en.wikipedia.org/wiki/Mipmap
Implementing it with DirectX will be 10x as difficult. Different graphics hardware has different maximum texture sizes. Most likely you will need to break your image up in to multiple textures to draw and you will also have to keep track of render states, viewing matrices, etc.
However, if you do use DirectX, you can implement lots of real-time photo adjustments You can do real-time rotation by simply adjusting view matrices. You can do real-time contrast, brightness, gamma, and sharpness easily in a pixel shader.
There are two other API's I might suggest. If you are willing to limit yourself to Vista or later then Direct2D would be a little simpler than Direct3D. Also if you ever will need to implement it on a non-windows platform I would suggest using OpenGL instead. My current project is in Direct3D because a few years ago when we started it OpenGL was falling behind and I didn't forsee the popularity of Android devices. I now wish we had used OpenGL instead.
Try profiling to see where WPF is spending its time. Are you displaying the images at their native resolution? If not it might be worthwhile to do some preprocessing and create 1/2 resolution versions.

C# fast pixel rendering

I'm developing depth processing (Xbox Kinect, Asus Xtion, etc) applications using OpenNI.
I need a really simple and fast way of drawing on a Windows form when new depth data is available from the sensor (30 or 60 fps depending on resolution).
Currently I'm invalidating a double-buffered panel from a seperate thread when the data becomes available, and then setting pixels of a bitmap in the panel's paint method, yielding a predictably awful 5fps.
System.Drawing.Graphics seems to lack a fast way to set individual pixels, unless anyone can instruct otherwise.
I literally just need to set pixel colours, so would like to avoid using third party high speed rendering APIs if possible, and ideally use something as native as possible.
Does anyone have any suggestions?
If you're using Bitmaps, then you should use LockBits and UnlockBits to access the data directly in memory. In C#, you can get some extra performance by using unsafe code blocks and pointers.
See this link for more information: http://web.archive.org/web/20150227183132/http://bobpowell.net/lockingbits.aspx
image.SetPixel() is very slow when you are replacing many pixels per frame and you need many frames per second.
It will be a lot faster when you use a WriteableBitmap and call CopyPixels
This way you can fill the array with pixel data using multiple threads and simply blit the array to the image in a single call.
EDIT
Note that WriteableBitmap is a WPF class. If you are bound to WinForms you might need to create your own implementation. WPF/WinForms/GDI interop: converting a WriteableBitmap to a System.Drawing.Image?
You could try my LINQ image processing library to work with your "buffer-bitmaps". It uses an accessible LINQ syntax but is very performant for large bitmaps. It is available on Nuget as a single file include in your project.
Hope that helps!

Categories

Resources