1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-13 10:33:07 +08:00

Fix draw FPS being inaccurate due to using ElapsedFrameTime

Had a feeling this would be the case.

Basically, we're calculating on the update thread and checking the last
value of draw thread's `ElapsedFrameTime`. In the case that value is
spiky, a completely incorrect fps can be displayed.

I've left the spike display do use `ElapsedFrameTime`, as
`FramesPerSecond` is too averaged to see spikes.
This commit is contained in:
Dean Herbert 2022-07-21 19:11:16 +09:00
parent 8f2287b968
commit 4c4939d18d

View File

@ -1,7 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@ -165,13 +164,14 @@ namespace osu.Game.Graphics.UserInterface
// TODO: this is wrong (elapsed clock time, not actual run time).
double newUpdateFrameTime = gameHost.UpdateThread.Clock.ElapsedFrameTime;
// use elapsed frame time rather then FramesPerSecond to better catch stutter frames.
double newDrawFps = 1000 / Math.Max(0.001, gameHost.DrawThread.Clock.ElapsedFrameTime);
double newDrawFrameTime = gameHost.DrawThread.Clock.ElapsedFrameTime;
double newDrawFps = gameHost.DrawThread.Clock.FramesPerSecond;
const double spike_time_ms = 20;
bool hasUpdateSpike = counterUpdateFrameTime.Current.Value < spike_time_ms && newUpdateFrameTime > spike_time_ms;
bool hasDrawSpike = counterDrawFPS.Current.Value > (1000 / spike_time_ms) && newDrawFps <= (1000 / spike_time_ms);
// use elapsed frame time rather then FramesPerSecond to better catch stutter frames.
bool hasDrawSpike = counterDrawFPS.Current.Value > (1000 / spike_time_ms) && newDrawFrameTime > spike_time_ms;
// If the frame time spikes up, make sure it shows immediately on the counter.
if (hasUpdateSpike)
@ -180,7 +180,8 @@ namespace osu.Game.Graphics.UserInterface
counterUpdateFrameTime.Current.Value = newUpdateFrameTime;
if (hasDrawSpike)
counterDrawFPS.SetCountWithoutRolling(newDrawFps);
// show spike time using raw elapsed value, to account for `FramesPerSecond` being so averaged spike frames don't show.
counterDrawFPS.SetCountWithoutRolling(1000 / newDrawFrameTime);
else
counterDrawFPS.Current.Value = newDrawFps;