Why can't I get a smooth 60 FPS animation in a WPF application when I run a control in the background thread in Windows 10?

I am trying to place a control in a background thread so that it can display animation at a constant frequency of 60 FPS, even if the user interface thread is blocked. This worked fine on Windows 8.1, but it has been failing since upgrading to Windows 10.

I am hooking the CompositionTarget.Rendering event from the background thread that hosts the control so that the animation can be in sync with the monitor refresh. But it seems that as soon as something in the main UI thread also catches the Rendering event, frames are skipped whenever the visual layout in the main UI thread changes.

I can visually see the skipped frames, and according to the RenderTime displayed in the RenderingEventArgs class, this confirms that the frames are skipped because the time delta since the last frame is about 33 ms instead of 16 ms when the frame misses.

The skip can be triggered by the inclusion of the CompositionTarget.Rendering event in the user interface thread and nothing is done in the event handler or when starting the storyboard animation, which, I think, is due to the fact that the storyboard animation captures the CompositionTarget.Rendering event to achieve smooth animation.

Here is a simple example demonstrating the problem:

SmoothAnimationTest.zip

I tested it in both Windows 8.1 and Windows 10 on several machines, in each case Windows 8.1 works fine with the native stream control, which runs at 60 FPS, no matter what. In Windows 10, “Show Judder 1” reduces the frame rate to a constant 30 FPS, and “Show Judder 2” causes the frame rate to switch randomly between 30 and 60 FPS, an average of about 45-50.

In both Windows 8.1 and Windows 10, pressing the “Block UI Thread” button results in a smooth 60 FPS in separate flow control.

The solution should be to execute the animation in the user interface stream and remove all the lock code from this stream, unfortunately, this is not an easy task, since the application I'm working on is complex, and there are many places where the user interface can be blocked for more than a few milliseconds, which can cause distortion in the animation.

+5
source share
1 answer

This may not be the full answer, but I thought it’s better not to write it as a comment.

Did you first confirm that the problem is not related to .Net 4.6? Win 10 ships with .Net 4.6, which replaces .Net 4.5, which comes with Win 8.1..Net 4.6, contains many internal changes and new bugs. I would install .Net 4.6 on Win 8.1 to test this as my first step ... (if the error is related to .Net 4.6, then you should report it via Connect , but you won’t get any hope. Take years to fix the error if at all)

Secondly, I don’t know exactly how you show your control, but it looks like you need a second dispatcher . This will require another window. Thus, no matter what happens in the main window, this will not affect the secondary window.

As I said, I do not know if this option is possible in your scenario. It’s possible to make the second window borderless, the top one and overlap with the first window ...

0
source

All Articles