mirror of
https://github.com/ppy/osu.git
synced 2024-11-13 18:07:25 +08:00
Better handle spikes and significant changes
This commit is contained in:
parent
285516b111
commit
705ff06ea5
@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -22,8 +21,8 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
{
|
{
|
||||||
public class FPSCounter : VisibilityContainer, IHasCustomTooltip
|
public class FPSCounter : VisibilityContainer, IHasCustomTooltip
|
||||||
{
|
{
|
||||||
private RollingCounter<double> msCounter = null!;
|
private RollingCounter<double> counterUpdateFrameTime = null!;
|
||||||
private RollingCounter<double> fpsCounter = null!;
|
private RollingCounter<double> counterDrawFPS = null!;
|
||||||
|
|
||||||
private Container mainContent = null!;
|
private Container mainContent = null!;
|
||||||
|
|
||||||
@ -68,14 +67,14 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
msCounter = new FrameTimeCounter
|
counterUpdateFrameTime = new FrameTimeCounter
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopRight,
|
Anchor = Anchor.TopRight,
|
||||||
Origin = Anchor.TopRight,
|
Origin = Anchor.TopRight,
|
||||||
Margin = new MarginPadding(1),
|
Margin = new MarginPadding(1),
|
||||||
Y = -2,
|
Y = -2,
|
||||||
},
|
},
|
||||||
fpsCounter = new FramesPerSecondCounter
|
counterDrawFPS = new FramesPerSecondCounter
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopRight,
|
Anchor = Anchor.TopRight,
|
||||||
Origin = Anchor.TopRight,
|
Origin = Anchor.TopRight,
|
||||||
@ -156,30 +155,47 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
// TODO: this is wrong (elapsed clock time, not actual run time).
|
double aimDrawFPS = gameHost.DrawThread.Clock.MaximumUpdateHz;
|
||||||
double newFrameTime = gameHost.UpdateThread.Clock.ElapsedFrameTime;
|
double aimUpdateFPS = gameHost.UpdateThread.Clock.MaximumUpdateHz;
|
||||||
double newFps = gameHost.DrawThread.Clock.FramesPerSecond;
|
|
||||||
|
|
||||||
bool hasSignificantChanges =
|
if (!gameHost.UpdateThread.Clock.Throttling)
|
||||||
Math.Abs(msCounter.Current.Value - newFrameTime) > 5 ||
|
{
|
||||||
Math.Abs(fpsCounter.Current.Value - newFps) > 10;
|
aimUpdateFPS = aimDrawFPS = gameHost.InputThread.Clock.MaximumUpdateHz;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 / gameHost.DrawThread.Clock.ElapsedFrameTime;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// If the frame time spikes up, make sure it shows immediately on the counter.
|
||||||
|
if (hasUpdateSpike)
|
||||||
|
counterUpdateFrameTime.SetCountWithoutRolling(newUpdateFrameTime);
|
||||||
|
else
|
||||||
|
counterUpdateFrameTime.Current.Value = newUpdateFrameTime;
|
||||||
|
|
||||||
|
if (hasDrawSpike)
|
||||||
|
counterDrawFPS.SetCountWithoutRolling(newDrawFps);
|
||||||
|
else
|
||||||
|
counterDrawFPS.Current.Value = newDrawFps;
|
||||||
|
|
||||||
|
counterDrawFPS.Colour = getColour(counterDrawFPS.DisplayedCount / aimDrawFPS);
|
||||||
|
|
||||||
|
double displayedUpdateFPS = 1000 / counterUpdateFrameTime.DisplayedCount;
|
||||||
|
counterUpdateFrameTime.Colour = getColour(displayedUpdateFPS / aimUpdateFPS);
|
||||||
|
|
||||||
|
bool hasSignificantChanges = hasDrawSpike
|
||||||
|
|| hasUpdateSpike
|
||||||
|
|| counterDrawFPS.DisplayedCount < aimDrawFPS * 0.8
|
||||||
|
|| displayedUpdateFPS < aimUpdateFPS * 0.8;
|
||||||
|
|
||||||
if (hasSignificantChanges)
|
if (hasSignificantChanges)
|
||||||
displayTemporarily();
|
displayTemporarily();
|
||||||
|
|
||||||
// If the frame time spikes up, make sure it shows immediately on the counter.
|
|
||||||
if (msCounter.Current.Value < 20 && newFrameTime > 20)
|
|
||||||
msCounter.SetCountWithoutRolling(newFrameTime);
|
|
||||||
else
|
|
||||||
msCounter.Current.Value = newFrameTime;
|
|
||||||
|
|
||||||
fpsCounter.Current.Value = newFps;
|
|
||||||
|
|
||||||
fpsCounter.Colour = getColour(fpsCounter.DisplayedCount / gameHost.DrawThread.Clock.MaximumUpdateHz);
|
|
||||||
|
|
||||||
double equivalentHz = 1000 / msCounter.DisplayedCount;
|
|
||||||
|
|
||||||
msCounter.Colour = getColour(equivalentHz / gameHost.UpdateThread.Clock.MaximumUpdateHz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ColourInfo getColour(double performanceRatio)
|
private ColourInfo getColour(double performanceRatio)
|
||||||
@ -196,7 +212,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
public class FramesPerSecondCounter : RollingCounter<double>
|
public class FramesPerSecondCounter : RollingCounter<double>
|
||||||
{
|
{
|
||||||
protected override double RollingDuration => 400;
|
protected override double RollingDuration => 1000;
|
||||||
|
|
||||||
protected override OsuSpriteText CreateSpriteText()
|
protected override OsuSpriteText CreateSpriteText()
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user