I am encountering a problem where a WPF application runs with a very low frame rate when a D3D application is running at the same time.
The situation is as follows: The first application is a Winforms form that renders 3D graphics using SlimDX and D3D10. The application doesn't run in fullscreen mode, but in a maximized window. This is very smooth and fast.
The second application consists of a WPF window that renders a ScatterView with some images. The WPF window is transparent (AllowsTransparency="True" with a transparent background). The general idea here is that the WPF window should look like it is composited on top of the 3D scene.
However, as soon as the D3D10 application is running, the performance of the WPF app deteriorates to as low as 1-2 fps (as measured by the WPF Performance Tool). That's not because my computer hardware is not capable of rendering both applications: the D3D10 app is always rendering the 3D scene very smoothly, and GPU and CPU utilization does not max out when I have both applications running. Even when I give the WPF app a higher process priority, the rendering performance stays at 1-2 fps.
I have also tried to combine both applications into a single process and using a D3DImage and using a shared D3D10 surface (with a D3D9Ex device) to feed it into the D3DImage. Furthermore I tried using an InteropBitmap and writing the frame data into it. All of those solutions work and produce a D3D10 scene with some WPF controls on top of it, but none of them make WPF run smoothly.
The idea of using two different application processes was my final idea to decouple the WPF rendering stack from any eventual performance impacts that may arise from having D3D10 render in the same process.
Related
I'm using Avalonia UI to create an application that is available for both Windows as well as macOS, and have come across the issue that, when using a macOS device that has a Retina display, the entire application is scaled up quite massively, estimated about two times. This means that my application, which, in its smallest form is about the size of the Windows Explorer default, actually falls outside of the screen on these Retina displays, which, of course, is not ideal.
Is there a solution?
I'm using CefSharp in WPF application in offscreen-mode.
Inside browser WebGL 3D model. At some points of model must be "billboard" but it must be WPF object in 2D space of WPF.
At each frame render I calculate projection of 3D point to 2D screen coords and send callback to WPF with 2D coords.
Visually 2D object of WPF moved on 1-2 frame faster than 3D model. It's strange because I'm catching onRender event of CEF and set billboards coords after browser render.
How I can synchronize render of 3D model and 2D billboards in WPF?
The culprit may be the fact that a WPF application does not have a predictable refresh rate. It redraws the UI based on under-the-hood heuristics influenced by your hardware and the current state of the OS. WPF cannot be forced to redraw at will unless you work around it with DirectDraw. Read in more detail here: https://rhnatiuk.wordpress.com/2008/12/21/wpf-video-playback-problems/
If you have continuous motion rendering within a WPF application, such as video, animation effects, or a browser with a WebGL-rendered moving object, you cannot reliably frame-sync it for screenshot purposes. I tried to run video in a WPF CefSharp app and the performance (perceived and measured) was abysmal on every (even high-end) computer I could find.
You can try to port your application into WinForms to benefit from constant frame rates. In WinForms, you would have to grab screenshots of the form or of the browser control which is messy but should be doable.
I am working on an application in WPF using Vlc.DotNet. I was having an issue with the video playing back with a terrible frame rate on my laptop.
After some research I identified that the issue is related to the CPU throttling down. If the laptop power profile is in BatterySaver mode it has the issue. If I switch it to performance, everything works fine. It seems to me like in BatterySaver mode it allows the processor to throttle down, and for some reason doesn't throttle back up correctly when the application needs it to. Is there anyway I can fix this issue?
I tried setting the priority with the code below and it didn't seem to make a difference.
System.Diagnostics.Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
Vlc.DotNet updates and ImageSource with the next rendered image. I have this source bound to an Image on the GUI that displays it. I used the WPF Performance Kit and can see what is happening, but not why. As soon as it starts playing, AKA updating the image on the GUI at 30fps, the frame rate of the entire application drops down to around 5fps.
Have you tried switching to software rendering to avoid the bottleneck of CPU power downs? I know WPF uses a separate thread for rendering and I'm not sure if you can even access it from Process.Threads. What I've done in the past is attach to the power mode changed event and switched the mode dynamically like this so power mode changes don't switch to hardware rendering. Not sure if this will work as I don't what your specific bottleneck is, but hopefully this points you in a good direction.
I'm using Spazzarama's Direct3DHook to capture screenshots from an application (with the purpose of streaming them over the Internet). Although this works well when the application uses DirectX, it fails if the application does not use DirectX (e.g. Notepad).
How can I determine whether a running application (process) uses DirectX? The reason is that in that case, I would need to use a different way to capture a screen, e.g. using GDI+.
When this DirectX application is not running in full screen mode, how do I get the size of the DirectX surface? E.g. when I capture the screen of a game running in windowed mode, the application size includes the size of the window frame etc. too, and my captured screen is typically too large.
I have an application which runs fullscreen on a high resolution display (1920x1080).
About 25% of the screen is a StackPanel that scrolls images across the screen.
(the X position is animated with double animation)
The scroll is very laggy and jumpy, and with visible tearing.
This is running on a brand new high-end gaming laptop, running Win7 64bit.
I don't understand why the performance is so poor. Am I doing something wrong? Does this kind of animation run on the CPU or GPU? Is there a smarter way to scroll images across the screen?
WPF can be hardware-accelerated, but only on newer video card drivers. Some of the onboard, out of box drivers, will default back to software rendering, which can feel really slow and clunky. As for the tearing, that's a normal video card setting, called V-Sync. I would try updating the video card drivers to a proprietary driver (nVidia, AMD, etc.), and enabling vertical sync on the card.
You can check to see if it falls into software, or hardware rendering using the methods explained here.
If that doesn't resolve the issue, the only other possibility I can think of is your animation/rendering is not synced to the GUI.
See this msdn article for more details.
A trick that I've seen that can get around this issue is to place a 3D object on your page, view it side on and rotate it e.g. for 4 images have a cube with an image set to each side.
Yes the rotation still requires GPU and processor time but it is taken care of internally by the WPF animation and so doesn't require interaction with code behind once set rolling.