Implement basic performance statistics (#53)
* implement basic frame time stats * added game frame time * made performancestatictics class non-static * report average framerate instead of current framerate
This commit is contained in:
parent
39ed14a3d6
commit
4038e63de1
5 changed files with 100 additions and 5 deletions
|
@ -22,8 +22,6 @@ namespace Ryujinx.Core
|
||||||
|
|
||||||
static Logging()
|
static Logging()
|
||||||
{
|
{
|
||||||
ExecutionTime.Start();
|
|
||||||
|
|
||||||
if (File.Exists(LogFileName)) File.Delete(LogFileName);
|
if (File.Exists(LogFileName)) File.Delete(LogFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,6 +154,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
||||||
|
|
||||||
private long GbpQueueBuffer(ServiceCtx Context, BinaryReader ParcelReader)
|
private long GbpQueueBuffer(ServiceCtx Context, BinaryReader ParcelReader)
|
||||||
{
|
{
|
||||||
|
Context.Ns.Statistics.RecordGameFrameTime();
|
||||||
|
|
||||||
//TODO: Errors.
|
//TODO: Errors.
|
||||||
int Slot = ParcelReader.ReadInt32();
|
int Slot = ParcelReader.ReadInt32();
|
||||||
int Unknown4 = ParcelReader.ReadInt32();
|
int Unknown4 = ParcelReader.ReadInt32();
|
||||||
|
|
87
Ryujinx.Core/PerformanceStatistics.cs
Normal file
87
Ryujinx.Core/PerformanceStatistics.cs
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text;
|
||||||
|
using System.Timers;
|
||||||
|
|
||||||
|
namespace Ryujinx.Core
|
||||||
|
{
|
||||||
|
public class PerformanceStatistics
|
||||||
|
{
|
||||||
|
Stopwatch ExecutionTime = new Stopwatch();
|
||||||
|
Timer ResetTimer = new Timer(1000);
|
||||||
|
|
||||||
|
long CurrentGameFrameEnded;
|
||||||
|
long CurrentSystemFrameEnded;
|
||||||
|
long CurrentSystemFrameStart;
|
||||||
|
long LastGameFrameEnded;
|
||||||
|
long LastSystemFrameEnded;
|
||||||
|
|
||||||
|
double AccumulatedGameFrameTime;
|
||||||
|
double AccumulatedSystemFrameTime;
|
||||||
|
double CurrentGameFrameTime;
|
||||||
|
double CurrentSystemFrameTime;
|
||||||
|
double PreviousGameFrameTime;
|
||||||
|
double PreviousSystemFrameTime;
|
||||||
|
public double GameFrameRate { get; private set; }
|
||||||
|
public double SystemFrameRate { get; private set; }
|
||||||
|
public long SystemFramesRendered;
|
||||||
|
public long GameFramesRendered;
|
||||||
|
public long ElapsedMilliseconds => ExecutionTime.ElapsedMilliseconds;
|
||||||
|
public long ElapsedMicroseconds => (long)
|
||||||
|
(((double)ExecutionTime.ElapsedTicks / Stopwatch.Frequency) * 1000000);
|
||||||
|
public long ElapsedNanoseconds => (long)
|
||||||
|
(((double)ExecutionTime.ElapsedTicks / Stopwatch.Frequency) * 1000000000);
|
||||||
|
|
||||||
|
public PerformanceStatistics()
|
||||||
|
{
|
||||||
|
ExecutionTime.Start();
|
||||||
|
ResetTimer.Elapsed += ResetTimerElapsed;
|
||||||
|
ResetTimer.AutoReset = true;
|
||||||
|
ResetTimer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetTimerElapsed(object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
ResetStatistics();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartSystemFrame()
|
||||||
|
{
|
||||||
|
PreviousSystemFrameTime = CurrentSystemFrameTime;
|
||||||
|
LastSystemFrameEnded = CurrentSystemFrameEnded;
|
||||||
|
CurrentSystemFrameStart = ElapsedMicroseconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EndSystemFrame()
|
||||||
|
{
|
||||||
|
CurrentSystemFrameEnded = ElapsedMicroseconds;
|
||||||
|
CurrentSystemFrameTime = CurrentSystemFrameEnded - CurrentSystemFrameStart;
|
||||||
|
AccumulatedSystemFrameTime += CurrentSystemFrameTime;
|
||||||
|
SystemFramesRendered++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RecordGameFrameTime()
|
||||||
|
{
|
||||||
|
CurrentGameFrameEnded = ElapsedMicroseconds;
|
||||||
|
CurrentGameFrameTime = CurrentGameFrameEnded - LastGameFrameEnded;
|
||||||
|
PreviousGameFrameTime = CurrentGameFrameTime;
|
||||||
|
LastGameFrameEnded = CurrentGameFrameEnded;
|
||||||
|
AccumulatedGameFrameTime += CurrentGameFrameTime;
|
||||||
|
GameFramesRendered++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetStatistics()
|
||||||
|
{
|
||||||
|
GameFrameRate = 1000 / ((AccumulatedGameFrameTime / GameFramesRendered) / 1000);
|
||||||
|
GameFrameRate = double.IsNaN(GameFrameRate) ? 0 : GameFrameRate;
|
||||||
|
SystemFrameRate = 1000 / ((AccumulatedSystemFrameTime / SystemFramesRendered) / 1000);
|
||||||
|
SystemFrameRate = double.IsNaN(SystemFrameRate) ? 0 : SystemFrameRate;
|
||||||
|
|
||||||
|
GameFramesRendered = 0;
|
||||||
|
SystemFramesRendered = 0;
|
||||||
|
AccumulatedGameFrameTime = 0;
|
||||||
|
AccumulatedSystemFrameTime = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ namespace Ryujinx.Core
|
||||||
|
|
||||||
public Hid Hid { get; private set; }
|
public Hid Hid { get; private set; }
|
||||||
public SetSys Settings { get; private set; }
|
public SetSys Settings { get; private set; }
|
||||||
|
public PerformanceStatistics Statistics { get; private set; }
|
||||||
|
|
||||||
public event EventHandler Finish;
|
public event EventHandler Finish;
|
||||||
|
|
||||||
|
@ -32,6 +33,8 @@ namespace Ryujinx.Core
|
||||||
|
|
||||||
Hid = new Hid(Ram);
|
Hid = new Hid(Ram);
|
||||||
|
|
||||||
|
Statistics = new PerformanceStatistics();
|
||||||
|
|
||||||
Os = new Horizon(this);
|
Os = new Horizon(this);
|
||||||
|
|
||||||
Os.HidSharedMem.MemoryMapped += Hid.ShMemMap;
|
Os.HidSharedMem.MemoryMapped += Hid.ShMemMap;
|
||||||
|
|
|
@ -166,9 +166,12 @@ namespace Ryujinx
|
||||||
|
|
||||||
protected override void OnRenderFrame(FrameEventArgs e)
|
protected override void OnRenderFrame(FrameEventArgs e)
|
||||||
{
|
{
|
||||||
|
Ns.Statistics.StartSystemFrame();
|
||||||
|
|
||||||
GL.Viewport(0, 0, Width, Height);
|
GL.Viewport(0, 0, Width, Height);
|
||||||
|
|
||||||
Title = $"Ryujinx Screen - (Vsync: {VSync} - FPS: {1f / e.Time:0})";
|
Title = $"Ryujinx Screen - (Vsync: {VSync} - FPS: {Ns.Statistics.SystemFrameRate:0} - Guest FPS: " +
|
||||||
|
$"{Ns.Statistics.GameFrameRate:0})";
|
||||||
|
|
||||||
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||||
|
|
||||||
|
@ -176,6 +179,8 @@ namespace Ryujinx
|
||||||
Renderer.Render();
|
Renderer.Render();
|
||||||
|
|
||||||
SwapBuffers();
|
SwapBuffers();
|
||||||
|
|
||||||
|
Ns.Statistics.EndSystemFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnResize(EventArgs e)
|
protected override void OnResize(EventArgs e)
|
||||||
|
|
Reference in a new issue