Added multiple flags with colours

Added way to set max flags
This commit is contained in:
Andy Adshead 2019-02-16 04:35:30 +00:00
parent 6cd69076d0
commit ca8a064135
9 changed files with 65 additions and 15 deletions

View file

@ -83,6 +83,7 @@ namespace Ryujinx.HLE
public void RecordSystemFrameTime()
{
RecordFrameTime(FrameTypeSystem);
Profile.FlagTime(TimingFlagType.SystemFrame);
}
public void RecordGameFrameTime()

View file

@ -32,20 +32,25 @@ namespace Ryujinx.Profiler
// Timing flags
private TimingFlag[] _timingFlags;
private long[] _timingFlagAverages;
private long[] _timingFlagLast;
private int _timingFlagCount;
private int _timingFlagIndex;
private const int MaxFlags = 500;
private int _maxFlags;
private Action<TimingFlag> _timingFlagCallback;
public InternalProfile(long history)
public InternalProfile(long history, int maxFlags)
{
Timers = new Dictionary<ProfileConfig, TimingInfo>();
_timingFlags = new TimingFlag[MaxFlags];
_timerQueue = new ConcurrentQueue<TimerQueueValue>();
_history = history;
_cleanupRunning = true;
_maxFlags = maxFlags;
Timers = new Dictionary<ProfileConfig, TimingInfo>();
_timingFlags = new TimingFlag[_maxFlags];
_timingFlagAverages = new long[(int)TimingFlagType.Count];
_timingFlagLast = new long[(int)TimingFlagType.Count];
_timerQueue = new ConcurrentQueue<TimerQueueValue>();
_history = history;
_cleanupRunning = true;
// Create cleanup thread.
_cleanupThread = new Thread(CleanupLoop);
@ -114,20 +119,36 @@ namespace Ryujinx.Profiler
public void FlagTime(TimingFlagType flagType)
{
int flagId = (int)flagType;
_timingFlags[_timingFlagIndex] = new TimingFlag()
{
FlagType = flagType,
Timestamp = PerformanceCounter.ElapsedTicks
};
if (++_timingFlagIndex >= MaxFlags)
if (++_timingFlagIndex >= _maxFlags)
{
_timingFlagIndex = 0;
}
_timingFlagCount = Math.Max(_timingFlagCount + 1, MaxFlags);
_timingFlagCount = Math.Max(_timingFlagCount + 1, _maxFlags);
// Work out average
if (_timingFlagLast[flagId] == 0)
{
_timingFlagAverages[flagId] = _timingFlags[_timingFlagIndex].Timestamp;
}
else
{
_timingFlagAverages[flagId] = (_timingFlags[_timingFlagIndex].Timestamp + _timingFlagLast[flagId]) / 2;
}
// Notify subscribers
_timingFlagCallback?.Invoke(_timingFlags[_timingFlagIndex]);
// Set last time for average
_timingFlagLast[flagId] = _timingFlags[_timingFlagIndex].Timestamp;
}
public void BeginProfile(ProfileConfig config)
@ -175,12 +196,12 @@ namespace Ryujinx.Profiler
public TimingFlag[] GetTimingFlags()
{
int count = Math.Max(_timingFlagCount, MaxFlags);
int count = Math.Max(_timingFlagCount, _maxFlags);
TimingFlag[] outFlags = new TimingFlag[count];
for (int i = 0, sourceIndex = _timingFlagIndex; i < count; i++, sourceIndex++)
{
if (sourceIndex >= MaxFlags)
if (sourceIndex >= _maxFlags)
sourceIndex = 0;
outFlags[i] = _timingFlags[sourceIndex];
}

View file

@ -29,6 +29,7 @@ namespace Ryujinx.Profiler
History = (long)(config.History * PerformanceCounter.TicksPerSecond),
MaxLevel = config.MaxLevel,
Controls = config.Controls,
MaxFlags = config.MaxFlags,
};
}
@ -39,7 +40,7 @@ namespace Ryujinx.Profiler
return false;
if (_profileInstance == null)
_profileInstance = new InternalProfile(_settings.History);
_profileInstance = new InternalProfile(_settings.History, _settings.MaxFlags);
return true;
#else

View file

@ -14,6 +14,9 @@
// Set the maximum profiling level. Higher values may cause a heavy load on your system but will allow you to profile in more detail
"max_level": 0,
// Sets the maximum number of flags to keep
"max_flags": 1000,
// Keyboard Controls
// https://github.com/opentk/opentk/blob/master/src/OpenTK/Input/Key.cs
"controls": {

View file

@ -15,6 +15,7 @@ namespace Ryujinx.Profiler
public string DumpPath { get; private set; }
public float UpdateRate { get; private set; }
public int MaxLevel { get; private set; }
public int MaxFlags { get; private set; }
public float History { get; private set; }
public NpadDebug Controls { get; private set; }

View file

@ -12,6 +12,7 @@ namespace Ryujinx.Profiler
public string DumpLocation { get; set; } = "";
public float UpdateRate { get; set; } = 0.1f;
public int MaxLevel { get; set; } = 0;
public int MaxFlags { get; set; } = 1000;
// 19531225 = 5 seconds in ticks
public long History { get; set; } = 19531225;

View file

@ -1,12 +1,17 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
namespace Ryujinx.Profiler
{
public enum TimingFlagType
{
FrameSwap,
FrameSwap = 0,
SystemFrame = 1,
// Update this for new flags
Count = 2,
}
public struct TimingFlag

View file

@ -24,7 +24,6 @@ namespace Ryujinx.Profiler.UI
private Action _clicked;
private bool _visible;
public ProfileButton(FontService fontService, Action clicked)
: this(fontService, clicked, 0, 0, 0, 0, 0)
{

View file

@ -7,6 +7,13 @@ namespace Ryujinx.Profiler.UI
{
public partial class ProfileWindow
{
// Colour index equal to timing flag type as int
private Color[] _timingFlagColours = new[]
{
new Color(150, 25, 25, 50), // FrameSwap = 0
new Color(25, 25, 150, 50), // SystemFrame = 1
};
private TimingFlag[] _timingFlags;
private const float GraphMoveSpeed = 40000;
@ -40,16 +47,27 @@ namespace Ryujinx.Profiler.UI
graphPositionTicks = _captureTime - graphPositionTicks;
// Draw timing flags
TimingFlagType prevType = TimingFlagType.Count;
GL.Enable(EnableCap.ScissorTest);
GL.Color3(0.25f, 0.25f, 0.25f);
GL.Enable(EnableCap.Blend);
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
GL.Begin(PrimitiveType.Lines);
foreach (TimingFlag timingFlag in _timingFlags)
{
if (prevType != timingFlag.FlagType)
{
prevType = timingFlag.FlagType;
GL.Color4(_timingFlagColours[(int)prevType]);
}
int x = (int)(graphRight - ((graphPositionTicks - timingFlag.Timestamp) / timeWidthTicks) * width);
GL.Vertex2(x, 0);
GL.Vertex2(x, Height);
}
GL.End();
GL.Disable(EnableCap.Blend);
// Draw bars
GL.Begin(PrimitiveType.Triangles);