ryujinx/Ryujinx.HLE/PerformanceStatistics.cs

119 lines
3.0 KiB
C#

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;
private double[] AverageFrameRate;
private double[] AccumulatedFrameTime;
private double[] PreviousFrameTime;
private long[] FramesRendered;
private object[] FrameLock;
private double TicksToSeconds;
private Stopwatch ExecutionTime;
private Timer ResetTimer;
public PerformanceStatistics()
{
AverageFrameRate = new double[2];
AccumulatedFrameTime = new double[2];
PreviousFrameTime = new double[2];
FramesRendered = new long[2];
FrameLock = new object[] { new object(), new object() };
ExecutionTime = new Stopwatch();
ExecutionTime.Start();
ResetTimer = new Timer(1000);
ResetTimer.Elapsed += ResetTimerElapsed;
ResetTimer.AutoReset = true;
ResetTimer.Start();
TicksToSeconds = 1.0 / Stopwatch.Frequency;
}
private void ResetTimerElapsed(object sender, ElapsedEventArgs e)
{
CalculateAverageFrameRate(FrameTypeSystem);
CalculateAverageFrameRate(FrameTypeGame);
}
private void CalculateAverageFrameRate(int FrameType)
{
double FrameRate = 0;
if (AccumulatedFrameTime[FrameType] > 0)
{
FrameRate = FramesRendered[FrameType] / AccumulatedFrameTime[FrameType];
}
lock (FrameLock[FrameType])
{
AverageFrameRate[FrameType] = LinearInterpolate(AverageFrameRate[FrameType], FrameRate);
FramesRendered[FrameType] = 0;
AccumulatedFrameTime[FrameType] = 0;
}
}
private double LinearInterpolate(double Old, double New)
{
return Old * (1.0 - FrameRateWeight) + New * FrameRateWeight;
}
public void RecordSystemFrameTime()
{
RecordFrameTime(FrameTypeSystem);
}
public void RecordGameFrameTime()
{
RecordFrameTime(FrameTypeGame);
}
private void RecordFrameTime(int FrameType)
{
double CurrentFrameTime = ExecutionTime.ElapsedTicks * TicksToSeconds;
double ElapsedFrameTime = CurrentFrameTime - PreviousFrameTime[FrameType];
PreviousFrameTime[FrameType] = CurrentFrameTime;
lock (FrameLock[FrameType])
{
AccumulatedFrameTime[FrameType] += ElapsedFrameTime;
FramesRendered[FrameType]++;
}
}
public double GetSystemFrameRate()
{
return AverageFrameRate[FrameTypeSystem];
}
public double GetGameFrameRate()
{
return AverageFrameRate[FrameTypeGame];
}
}
}