I'm measuring the time between frames in a simple WPF animation. Perforator says the app performs at ~60fps, so I expected the time between frames to be ~16.6ms with little deviation.
public MainWindow()
{
...
CompositionTarget.Rendering += Rendering;
}
List<long> FrameDurations = new List<long>();
private long PreviousFrameTime = 0;
private void Rendering(object o, EventArgs args)
{
FrameDurations.Add(DateTime.Now.Ticks - PreviousFrameTime);
PreviousFrameTime = DateTime.Now.Ticks;
}
Two things surprised me:
- Time between frames is fairly irregular
- Time between frames is ~8ms. I had expected that the monitor's refresh rate would set a lower bound on time between frames (ie. 60Hz = 16.6ms between each frame, and anything faster is pointless).
Y - Time between frames in ticks (10,000 ticks = 1ms)
X - Frame count
Possible confounding factors
- Timer inaccuracy
- If CompositionTarget.Rendering doesn't actually correlate to the drawing of a single frame
The project I'm using: SimpleWindow.zip
===Edit
Markus pointed out I could be using RenderingEventArgs.RenderingTime.Ticks instead of DateTime.Now.Ticks. I repeated the run and got very different results. The only difference is timing method:
DateTime.Now.Ticks
RenderingEventArgs.RenderingTime.Ticks
Data from RenderingEventArgs produced data much closer the expected 16.6ms/frame, and it is consistent.
- I'm not sure why DateTime.Now and RenderingEventArgs would produce such very different data.
- Assuming RenderingEventArgs is producing correct times, it's still a bit disconcerting that those times are not the expected 16.6ms.
If the display is updating every 16.6ms and WPF is updating every 14.9ms, we can expect a race condition that would result in tearing. That is to say, roughly every 10th frame WPF will be trying to write its image while the display is trying to read the image.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…