e7559f128f
* Call OpenGL functions directly, remove the pfifo thread, some refactoring * Fix PerformanceStatistics calculating the wrong host fps, remove wait event on PFIFO as this wasn't exactly was causing the freezes (may replace with an exception later) * Organized the Gpu folder a bit more, renamed a few things, address PR feedback * Make PerformanceStatistics thread safe * Remove unused constant * Use unlimited update rate for better pref
120 lines
3.0 KiB
C#
120 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];
|
|
}
|
|
}
|
|
}
|