diff options
Diffstat (limited to 'src/Ryujinx.HLE/PerformanceStatistics.cs')
-rw-r--r-- | src/Ryujinx.HLE/PerformanceStatistics.cs | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/src/Ryujinx.HLE/PerformanceStatistics.cs b/src/Ryujinx.HLE/PerformanceStatistics.cs new file mode 100644 index 00000000..95fc2abe --- /dev/null +++ b/src/Ryujinx.HLE/PerformanceStatistics.cs @@ -0,0 +1,167 @@ +using Ryujinx.Common; +using System.Timers; + +namespace Ryujinx.HLE +{ + public class PerformanceStatistics + { + private const int FrameTypeGame = 0; + private const int PercentTypeFifo = 0; + + private double[] _frameRate; + private double[] _accumulatedFrameTime; + private double[] _previousFrameTime; + + private double[] _averagePercent; + private double[] _accumulatedActiveTime; + private double[] _percentLastEndTime; + private double[] _percentStartTime; + + private long[] _framesRendered; + private double[] _percentTime; + + private object[] _frameLock; + private object[] _percentLock; + + private double _ticksToSeconds; + + private Timer _resetTimer; + + public PerformanceStatistics() + { + _frameRate = new double[1]; + _accumulatedFrameTime = new double[1]; + _previousFrameTime = new double[1]; + + _averagePercent = new double[1]; + _accumulatedActiveTime = new double[1]; + _percentLastEndTime = new double[1]; + _percentStartTime = new double[1]; + + _framesRendered = new long[1]; + _percentTime = new double[1]; + + _frameLock = new object[] { new object() }; + _percentLock = new object[] { new object() }; + + _resetTimer = new Timer(750); + + _resetTimer.Elapsed += ResetTimerElapsed; + _resetTimer.AutoReset = true; + + _resetTimer.Start(); + + _ticksToSeconds = 1.0 / PerformanceCounter.TicksPerSecond; + } + + private void ResetTimerElapsed(object sender, ElapsedEventArgs e) + { + CalculateFrameRate(FrameTypeGame); + CalculateAveragePercent(PercentTypeFifo); + } + + private void CalculateFrameRate(int frameType) + { + double frameRate = 0; + + lock (_frameLock[frameType]) + { + if (_accumulatedFrameTime[frameType] > 0) + { + frameRate = _framesRendered[frameType] / _accumulatedFrameTime[frameType]; + } + + _frameRate[frameType] = frameRate; + _framesRendered[frameType] = 0; + _accumulatedFrameTime[frameType] = 0; + } + } + + private void CalculateAveragePercent(int percentType) + { + // If start time is non-zero, a percent reading is still being measured. + // If there aren't any readings, the default should be 100% if still being measured, or 0% if not. + double percent = (_percentStartTime[percentType] == 0) ? 0 : 100; + + lock (_percentLock[percentType]) + { + if (_percentTime[percentType] > 0) + { + percent = (_accumulatedActiveTime[percentType] / _percentTime[percentType]) * 100; + } + + _averagePercent[percentType] = percent; + _percentTime[percentType] = 0; + _accumulatedActiveTime[percentType] = 0; + } + } + + public void RecordGameFrameTime() + { + RecordFrameTime(FrameTypeGame); + } + + public void RecordFifoStart() + { + StartPercentTime(PercentTypeFifo); + } + + public void RecordFifoEnd() + { + EndPercentTime(PercentTypeFifo); + } + + private void StartPercentTime(int percentType) + { + double currentTime = PerformanceCounter.ElapsedTicks * _ticksToSeconds; + + _percentStartTime[percentType] = currentTime; + } + + private void EndPercentTime(int percentType) + { + double currentTime = PerformanceCounter.ElapsedTicks * _ticksToSeconds; + double elapsedTime = currentTime - _percentLastEndTime[percentType]; + double elapsedActiveTime = currentTime - _percentStartTime[percentType]; + + lock (_percentLock[percentType]) + { + _accumulatedActiveTime[percentType] += elapsedActiveTime; + _percentTime[percentType] += elapsedTime; + } + + _percentLastEndTime[percentType] = currentTime; + _percentStartTime[percentType] = 0; + } + + private void RecordFrameTime(int frameType) + { + double currentFrameTime = PerformanceCounter.ElapsedTicks * _ticksToSeconds; + double elapsedFrameTime = currentFrameTime - _previousFrameTime[frameType]; + + _previousFrameTime[frameType] = currentFrameTime; + + lock (_frameLock[frameType]) + { + _accumulatedFrameTime[frameType] += elapsedFrameTime; + + _framesRendered[frameType]++; + } + } + + public double GetGameFrameRate() + { + return _frameRate[FrameTypeGame]; + } + + public double GetFifoPercent() + { + return _averagePercent[PercentTypeFifo]; + } + + public double GetGameFrameTime() + { + return 1000 / _frameRate[FrameTypeGame]; + } + } +}
\ No newline at end of file |