Improve FPS smoothing to initialize with a real value instead of ramping up from zero. Re-initialize the FPS data after pausing or changing fast forward/rewind state to eliminate ramp-up and ramp-down in those cases. Only the initial behavior has changed; the FPS calculation/smoothing is otherwise mathematically identical.

This commit is contained in:
J.D. Purcell 2016-12-16 16:01:21 -05:00
parent eda79c2212
commit 7843664f68
1 changed files with 65 additions and 46 deletions

View File

@ -487,6 +487,8 @@ namespace BizHawk.Client.EmuHawk
Activate();
BringToFront();
InitializeFpsData();
for (;;)
{
Input.Instance.Update();
@ -584,6 +586,11 @@ namespace BizHawk.Client.EmuHawk
private set
{
if (_emulatorPaused && !value) // Unpausing
{
InitializeFpsData();
}
_emulatorPaused = value;
if (OnPauseChanged != null)
{
@ -1358,15 +1365,16 @@ namespace BizHawk.Client.EmuHawk
private bool _runloopFrameProgress;
private long _frameAdvanceTimestamp;
private long _frameRewindTimestamp;
private double _runloopLastFps;
private double _runloopDisplayFps;
private bool _runloopFrameadvance;
private double _runloopUpdatesPerSecond = 12.0;
private double _runloopFpsSmoothing = 8.0;
private long _runloopSecond;
private bool _runloopLastFf;
private bool _lastFastForwardingOrRewinding;
private bool _inResizeLoop;
private readonly double _fpsUpdatesPerSecond = 12.0;
private readonly double _fpsSmoothing = 8.0;
private double _lastFps;
private int _framesSinceLastFpsUpdate;
private long _timestampLastFpsUpdate;
private readonly Throttle _throttle;
private bool _unthrottled;
@ -1416,7 +1424,7 @@ namespace BizHawk.Client.EmuHawk
//we need to display FPS somewhere, in this case
if (Global.Config.DispSpeedupFeatures == 0)
{
str = str + string.Format("({0:0} fps) -", _runloopDisplayFps);
str = str + string.Format("({0:0} fps) -", _lastFps);
}
if (!string.IsNullOrEmpty(VersionInfo.CustomBuildString))
@ -2757,8 +2765,13 @@ namespace BizHawk.Client.EmuHawk
if (runFrame || force)
{
var isFastForwarding = Global.ClientControls["Fast Forward"] || IsTurboing;
var updateFpsString = _runloopLastFf != isFastForwarding;
_runloopLastFf = isFastForwarding;
var isFastFowardingOrRewinding = isFastForwarding || isRewinding;
if (isFastFowardingOrRewinding != _lastFastForwardingOrRewinding)
{
InitializeFpsData();
}
_lastFastForwardingOrRewinding = isFastFowardingOrRewinding;
// client input-related duties
GlobalWin.OSD.ClearGUIText();
@ -2783,9 +2796,9 @@ namespace BizHawk.Client.EmuHawk
GlobalWin.Tools.UpdateToolsBefore();
}
_runloopLastFps+= _runloopFpsSmoothing;
_framesSinceLastFpsUpdate++;
UpdateFpsDisplay(currentTimestamp, updateFpsString, isRewinding, isFastForwarding);
UpdateFpsDisplay(currentTimestamp, isRewinding, isFastForwarding);
CaptureRewind(suppressCaptureRewind);
@ -2794,7 +2807,7 @@ namespace BizHawk.Client.EmuHawk
{
atten = Global.Config.SoundVolume / 100.0f;
if (isFastForwarding || IsTurboing || isRewinding)
if (isFastFowardingOrRewinding)
{
if (Global.Config.SoundEnabledRWFF)
atten *= Global.Config.SoundVolumeRWFF / 100.0f;
@ -2884,46 +2897,52 @@ namespace BizHawk.Client.EmuHawk
GlobalWin.Sound.UpdateSound(atten);
}
private void UpdateFpsDisplay(long currentTimestamp, bool updateFpsString, bool isRewinding, bool isFastForwarding)
private void UpdateFpsDisplay(long currentTimestamp, bool isRewinding, bool isFastForwarding)
{
var timeDiff = (currentTimestamp - _runloopSecond);
if ( timeDiff * _runloopUpdatesPerSecond >= Stopwatch.Frequency)
double elapsedSeconds = (currentTimestamp - _timestampLastFpsUpdate) / (double)Stopwatch.Frequency;
if (elapsedSeconds < 1.0 / _fpsUpdatesPerSecond)
{
_runloopLastFps = Stopwatch.Frequency * (_runloopLastFps / (Stopwatch.Frequency + timeDiff * _runloopFpsSmoothing));
_runloopSecond = currentTimestamp;
_runloopDisplayFps = _runloopLastFps;
updateFpsString = true;
return;
}
if (updateFpsString)
if (_lastFps == 0) // Initial calculation
{
var fps_string = string.Format("{0:0} fps", _runloopDisplayFps);
if (isRewinding)
{
if (IsTurboing || isFastForwarding)
{
fps_string += " <<<<";
}
else
{
fps_string += " <<";
}
}
else if (IsTurboing)
{
fps_string += " >>>>";
}
else if (isFastForwarding)
{
fps_string += " >>";
}
GlobalWin.OSD.FPS = fps_string;
//need to refresh window caption in this case
if (Global.Config.DispSpeedupFeatures == 0)
SetWindowText();
_lastFps = (_framesSinceLastFpsUpdate - 1) / elapsedSeconds;
}
else
{
_lastFps = (_lastFps + (_framesSinceLastFpsUpdate * _fpsSmoothing)) / (1.0 + (elapsedSeconds * _fpsSmoothing));
}
_framesSinceLastFpsUpdate = 0;
_timestampLastFpsUpdate = currentTimestamp;
var fps_string = string.Format("{0:0} fps", _lastFps);
if (isRewinding)
{
fps_string += IsTurboing || isFastForwarding ?
" <<<<" :
" <<";
}
else if (isFastForwarding)
{
fps_string += IsTurboing ?
" >>>>" :
" >>";
}
GlobalWin.OSD.FPS = fps_string;
//need to refresh window caption in this case
if (Global.Config.DispSpeedupFeatures == 0)
SetWindowText();
}
private void InitializeFpsData()
{
_lastFps = 0;
_timestampLastFpsUpdate = Stopwatch.GetTimestamp();
_framesSinceLastFpsUpdate = 0;
}
#endregion