From 1b076a6836670ac06481fc9b0c3958d0e49a611a Mon Sep 17 00:00:00 2001 From: Andy Adshead Date: Mon, 28 Jan 2019 19:02:19 +0000 Subject: [PATCH] Dummy graph view with button to toggle --- Ryujinx.Profiler/UI/ProfileWindow.cs | 43 ++++++++---- Ryujinx.Profiler/UI/ProfileWindowGraph.cs | 85 +++++++++++++++++++++++ 2 files changed, 115 insertions(+), 13 deletions(-) create mode 100644 Ryujinx.Profiler/UI/ProfileWindowGraph.cs diff --git a/Ryujinx.Profiler/UI/ProfileWindow.cs b/Ryujinx.Profiler/UI/ProfileWindow.cs index 5b36e377c5..827bc5fc33 100644 --- a/Ryujinx.Profiler/UI/ProfileWindow.cs +++ b/Ryujinx.Profiler/UI/ProfileWindow.cs @@ -22,9 +22,10 @@ namespace Ryujinx.Profiler.UI FilterBar = 4, ShowHideInactive = 5, Pause = 6, + ChangeDisplay = 7, // Update this when new buttons are added - Count = 7, + Count = 8, } // Font service @@ -40,6 +41,8 @@ namespace Ryujinx.Profiler.UI private bool _viewportUpdated = true; private bool _redrawPending = true; + private bool _displayGraph = true; + private bool _showInactive = true; private bool _paused = false; @@ -118,11 +121,12 @@ namespace Ryujinx.Profiler.UI _fontService.UpdateScreenHeight(Height); _buttons = new ProfileButton[(int)ButtonIndex.Count]; - _buttons[(int)ButtonIndex.TagTitle] = new ProfileButton(_fontService, () => SetSort(new ProfileSorters.TagAscending())); - _buttons[(int)ButtonIndex.InstantTitle] = new ProfileButton(_fontService, () => SetSort(new ProfileSorters.InstantAscending())); - _buttons[(int)ButtonIndex.AverageTitle] = new ProfileButton(_fontService, () => SetSort(new ProfileSorters.AverageAscending())); - _buttons[(int)ButtonIndex.TotalTitle] = new ProfileButton(_fontService, () => SetSort(new ProfileSorters.TotalAscending())); - _buttons[(int)ButtonIndex.FilterBar] = new ProfileButton(_fontService, () => + _buttons[(int)ButtonIndex.TagTitle] = new ProfileButton(_fontService, () => SetSort(new ProfileSorters.TagAscending())); + _buttons[(int)ButtonIndex.InstantTitle] = new ProfileButton(_fontService, () => SetSort(new ProfileSorters.InstantAscending())); + _buttons[(int)ButtonIndex.AverageTitle] = new ProfileButton(_fontService, () => SetSort(new ProfileSorters.AverageAscending())); + _buttons[(int)ButtonIndex.TotalTitle] = new ProfileButton(_fontService, () => SetSort(new ProfileSorters.TotalAscending())); + _buttons[(int)ButtonIndex.ChangeDisplay] = new ProfileButton(_fontService, () => _displayGraph = !_displayGraph); + _buttons[(int)ButtonIndex.FilterBar] = new ProfileButton(_fontService, () => { _profileUpdated = true; _regexEnabled = !_regexEnabled; @@ -411,7 +415,14 @@ namespace Ryujinx.Profiler.UI #endregion // Time bars - DrawBars(xOffset, yOffset); + if (_displayGraph) + { + DrawGraph(xOffset, yOffset); + } + else + { + DrawBars(xOffset, yOffset); + } _fontService.DrawText("Blue: Instant, Green: Avg, Red: Total", xOffset, Height - TitleFontHeight, TitleFontHeight); xOffset = Width - 360; @@ -447,11 +458,14 @@ namespace Ryujinx.Profiler.UI float widthShowHideButton = _buttons[(int)ButtonIndex.ShowHideInactive].UpdateSize($"{(_showInactive ? "Hide" : "Show")} Inactive", 5, 5, 4, 16); // Play/Pause - width = _buttons[(int)ButtonIndex.Pause].UpdateSize(_paused ? "Play" : "Pause", 15 + (int)widthShowHideButton, 5, 4, 16) + widthShowHideButton; + float widthPlayPauseButton = _buttons[(int)ButtonIndex.Pause].UpdateSize(_paused ? "Play" : "Pause", 15 + (int)widthShowHideButton, 5, 4, 16) + widthShowHideButton; + + // Change display + width = _buttons[(int)ButtonIndex.ChangeDisplay].UpdateSize($"View: {(_displayGraph ? "Graph" : "Bars")}", 25 + (int)widthPlayPauseButton, 5, 4, 16) + widthPlayPauseButton; // Filter bar - _fontService.DrawText($"{(_regexEnabled ? "Regex " : "Filter")}: {_filterText}", 25 + width, 7, 16); - _buttons[(int) ButtonIndex.FilterBar].UpdateSize((int)(25 + width), 0, 0, Width, FilterHeight); + _fontService.DrawText($"{(_regexEnabled ? "Regex " : "Filter")}: {_filterText}", 35 + width, 7, 16); + _buttons[(int) ButtonIndex.FilterBar].UpdateSize((int)(35 + width), 0, 0, Width, FilterHeight); #endregion // Draw buttons @@ -472,12 +486,15 @@ namespace Ryujinx.Profiler.UI GL.Vertex2(0, FilterHeight); GL.Vertex2(Width, FilterHeight); - // Bottom vertical divider + // Bottom vertical dividers GL.Vertex2(widthShowHideButton + 10, 0); GL.Vertex2(widthShowHideButton + 10, FilterHeight); - GL.Vertex2(width + 20, 0); - GL.Vertex2(width + 20, FilterHeight); + GL.Vertex2(widthPlayPauseButton + 20, 0); + GL.Vertex2(widthPlayPauseButton + 20, FilterHeight); + + GL.Vertex2(width + 30, 0); + GL.Vertex2(width + 30, FilterHeight); GL.End(); #endregion diff --git a/Ryujinx.Profiler/UI/ProfileWindowGraph.cs b/Ryujinx.Profiler/UI/ProfileWindowGraph.cs new file mode 100644 index 0000000000..b26b0643e6 --- /dev/null +++ b/Ryujinx.Profiler/UI/ProfileWindowGraph.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenTK; +using OpenTK.Graphics.OpenGL; + +namespace Ryujinx.Profiler.UI +{ + public partial class ProfileWindow + { + private void DrawGraph(float xOffset, float yOffset) + { + if (_sortedProfileData.Count != 0) + { + long maxAverage; + long maxTotal; + + int verticalIndex = 0; + float barHeight = (LineHeight - LinePadding) / 3.0f; + float width = Width - xOffset - 370; + + // Get max values + var maxInstant = maxAverage = maxTotal = 0; + foreach (KeyValuePair kvp in _sortedProfileData) + { + maxInstant = Math.Max(maxInstant, kvp.Value.Instant); + maxAverage = Math.Max(maxAverage, kvp.Value.AverageTime); + maxTotal = Math.Max(maxTotal, kvp.Value.TotalTime); + } + + GL.Enable(EnableCap.ScissorTest); + GL.Begin(PrimitiveType.Triangles); + foreach (var entry in _sortedProfileData) + { + // Instant + GL.Color3(Color.Purple); + float bottom = GetLineY(yOffset, LineHeight, LinePadding, true, verticalIndex++); + float top = bottom + barHeight; + float right = (float)entry.Value.Instant / maxInstant * width + xOffset; + + // Skip rendering out of bounds bars + if (top < 0 || bottom > Height) + continue; + + GL.Vertex2(xOffset, bottom); + GL.Vertex2(xOffset, top); + GL.Vertex2(right, top); + + GL.Vertex2(right, top); + GL.Vertex2(right, bottom); + GL.Vertex2(xOffset, bottom); + + // Average + GL.Color3(Color.Purple); + top += barHeight; + bottom += barHeight; + right = (float)entry.Value.AverageTime / maxAverage * width + xOffset; + GL.Vertex2(xOffset, bottom); + GL.Vertex2(xOffset, top); + GL.Vertex2(right, top); + + GL.Vertex2(right, top); + GL.Vertex2(right, bottom); + GL.Vertex2(xOffset, bottom); + + // Total + GL.Color3(Color.Purple); + top += barHeight; + bottom += barHeight; + right = (float)entry.Value.TotalTime / maxTotal * width + xOffset; + GL.Vertex2(xOffset, bottom); + GL.Vertex2(xOffset, top); + GL.Vertex2(right, top); + + GL.Vertex2(right, top); + GL.Vertex2(right, bottom); + GL.Vertex2(xOffset, bottom); + } + + GL.End(); + GL.Disable(EnableCap.ScissorTest); + } + } + } +}