Ryujinx/Ryujinx.HLE/PerformanceStatistics.cs

119 lines
3.1 KiB
C#
Raw Normal View History

using System.Diagnostics;
using System.Timers;
namespace Ryujinx.HLE
{
public class PerformanceStatistics
{
private const double FrameRateWeight = 0.5;
private const int FrameTypeSystem = 0;
private const int FrameTypeGame = 1;
2018-12-01 21:01:59 +01:00
private double[] _averageFrameRate;
private double[] _accumulatedFrameTime;
private double[] _previousFrameTime;
2018-12-01 21:01:59 +01:00
private long[] _framesRendered;
2018-12-01 21:01:59 +01:00
private object[] _frameLock;
2018-12-01 21:01:59 +01:00
private double _ticksToSeconds;
2018-12-01 21:01:59 +01:00
private Stopwatch _executionTime;
2018-12-01 21:01:59 +01:00
private Timer _resetTimer;
public PerformanceStatistics()
{
2018-12-01 21:01:59 +01:00
_averageFrameRate = new double[2];
_accumulatedFrameTime = new double[2];
_previousFrameTime = new double[2];
2018-12-01 21:01:59 +01:00
_framesRendered = new long[2];
2018-12-01 21:01:59 +01:00
_frameLock = new object[] { new object(), new object() };
2018-12-01 21:01:59 +01:00
_executionTime = new Stopwatch();
2018-12-01 21:01:59 +01:00
_executionTime.Start();
2018-12-01 21:01:59 +01:00
_resetTimer = new Timer(1000);
2018-12-01 21:01:59 +01:00
_resetTimer.Elapsed += ResetTimerElapsed;
2018-12-01 21:01:59 +01:00
_resetTimer.AutoReset = true;
2018-12-01 21:01:59 +01:00
_resetTimer.Start();
2018-12-01 21:01:59 +01:00
_ticksToSeconds = 1.0 / Stopwatch.Frequency;
}
private void ResetTimerElapsed(object sender, ElapsedEventArgs e)
{
CalculateAverageFrameRate(FrameTypeSystem);
CalculateAverageFrameRate(FrameTypeGame);
}
2018-12-01 21:01:59 +01:00
private void CalculateAverageFrameRate(int frameType)
{
2018-12-01 21:01:59 +01:00
double frameRate = 0;
2018-12-01 21:01:59 +01:00
if (_accumulatedFrameTime[frameType] > 0)
{
2018-12-01 21:01:59 +01:00
frameRate = _framesRendered[frameType] / _accumulatedFrameTime[frameType];
}
2018-12-01 21:01:59 +01:00
lock (_frameLock[frameType])
{
2018-12-01 21:01:59 +01:00
_averageFrameRate[frameType] = LinearInterpolate(_averageFrameRate[frameType], frameRate);
2018-12-01 21:01:59 +01:00
_framesRendered[frameType] = 0;
2018-12-01 21:01:59 +01:00
_accumulatedFrameTime[frameType] = 0;
}
}
2018-12-01 21:01:59 +01:00
private double LinearInterpolate(double old, double New)
{
2018-12-01 21:01:59 +01:00
return old * (1.0 - FrameRateWeight) + New * FrameRateWeight;
}
public void RecordSystemFrameTime()
{
RecordFrameTime(FrameTypeSystem);
}
public void RecordGameFrameTime()
{
RecordFrameTime(FrameTypeGame);
}
2018-12-01 21:01:59 +01:00
private void RecordFrameTime(int frameType)
{
2018-12-01 21:01:59 +01:00
double currentFrameTime = _executionTime.ElapsedTicks * _ticksToSeconds;
2018-12-01 21:01:59 +01:00
double elapsedFrameTime = currentFrameTime - _previousFrameTime[frameType];
2018-12-01 21:01:59 +01:00
_previousFrameTime[frameType] = currentFrameTime;
2018-12-01 21:01:59 +01:00
lock (_frameLock[frameType])
{
2018-12-01 21:01:59 +01:00
_accumulatedFrameTime[frameType] += elapsedFrameTime;
2018-12-01 21:01:59 +01:00
_framesRendered[frameType]++;
}
}
public double GetSystemFrameRate()
{
2018-12-01 21:01:59 +01:00
return _averageFrameRate[FrameTypeSystem];
}
public double GetGameFrameRate()
{
2018-12-01 21:01:59 +01:00
return _averageFrameRate[FrameTypeGame];
}
}
}