Optimisations in drawing routine:

Only calculate bar top and bottom once per bar rather than once per timestamp
Pre-calculate the right side of the graph as it was being calculated multiple times per bar
Skip rendering timestamps that occupy the same pixel space now uses the raw timestamp to decide. While technically not as accurate it's much easier as the right side of the bar doesn't have to be calculated for a skipped timestamp
This commit is contained in:
Andy Adshead 2019-02-02 03:30:38 +00:00
parent aef7582888
commit 5a3cac991c

View file

@ -22,26 +22,30 @@ namespace Ryujinx.Profiler.UI
int left, right;
float top, bottom;
int verticalIndex = 0;
float barHeight = (LineHeight - LinePadding);
long history = Profile.HistoryLength;
long timeWidthTicks = (long)(history / (double)_graphZoom);
long graphPositionTicks = (long)(_graphPosition * PerformanceCounter.TicksPerMillisecond);
int verticalIndex = 0;
float graphRight = xOffset + width;
float barHeight = (LineHeight - LinePadding);
long history = Profile.HistoryLength;
double timeWidthTicks = history / (double)_graphZoom;
long graphPositionTicks = (long)(_graphPosition * PerformanceCounter.TicksPerMillisecond);
long ticksPerPixel = (long)(timeWidthTicks / width);
// Reset start point if out of bounds
if (timeWidthTicks + graphPositionTicks > history)
{
graphPositionTicks = history - timeWidthTicks;
graphPositionTicks = history - (long)timeWidthTicks;
_graphPosition = (float)graphPositionTicks / PerformanceCounter.TicksPerMillisecond;
}
graphPositionTicks = _captureTime - graphPositionTicks;
// Draw timing flags
GL.Enable(EnableCap.ScissorTest);
GL.Color3(0.25f, 0.25f, 0.25f);
GL.Begin(PrimitiveType.Lines);
foreach (TimingFlag timingFlag in _timingFlags)
{
int x = (int)(xOffset + width - ((float)(_captureTime - (timingFlag.Timestamp + graphPositionTicks)) / timeWidthTicks) * width);
int x = (int)(graphRight - ((graphPositionTicks - timingFlag.Timestamp) / timeWidthTicks) * width);
GL.Vertex2(x, 0);
GL.Vertex2(x, Height);
}
@ -51,30 +55,30 @@ namespace Ryujinx.Profiler.UI
GL.Begin(PrimitiveType.Triangles);
foreach (var entry in _sortedProfileData)
{
int furthest = 0;
long furthest = 0;
bottom = GetLineY(yOffset, LineHeight, LinePadding, true, verticalIndex);
top = bottom + barHeight;
// Skip rendering out of bounds bars
if (top < 0 || bottom > Height)
continue;
GL.Color3(Color.Green);
foreach (Timestamp timestamp in entry.Value.GetAllTimestamps())
{
right = (int)(xOffset + width - ((float)(_captureTime - (timestamp.EndTime + graphPositionTicks)) / timeWidthTicks) * width);
// Skip drawing multiple timestamps on same pixel
if (right <= furthest)
if (timestamp.EndTime < furthest)
continue;
furthest = timestamp.EndTime + ticksPerPixel;
left = (int)(xOffset + width - ((float)(_captureTime - (timestamp.BeginTime + graphPositionTicks)) / timeWidthTicks) * width);
bottom = GetLineY(yOffset, LineHeight, LinePadding, true, verticalIndex);
top = bottom + barHeight;
left = (int)(graphRight - ((graphPositionTicks - timestamp.BeginTime) / timeWidthTicks) * width);
right = (int)(graphRight - ((graphPositionTicks - timestamp.EndTime) / timeWidthTicks) * width);
// Make sure width is at least 1px
right = Math.Max(left + 1, right);
furthest = right;
// Skip rendering out of bounds bars
if (top < 0 || bottom > Height)
continue;
GL.Vertex2(left, bottom);
GL.Vertex2(left, top);
GL.Vertex2(right, top);
@ -84,30 +88,23 @@ namespace Ryujinx.Profiler.UI
GL.Vertex2(left, bottom);
}
GL.Color3(Color.Red);
// Currently capturing timestamp
GL.Color3(Color.Red);
long entryBegin = entry.Value.BeginTime;
if (entryBegin != -1)
{
left = (int)(xOffset + width + _graphPosition - (((float)_captureTime - entryBegin) / timeWidthTicks) * width);
bottom = GetLineY(yOffset, LineHeight, LinePadding, true, verticalIndex);
top = bottom + barHeight;
right = (int)(xOffset + width);
left = (int)(graphRight - ((graphPositionTicks - entryBegin) / timeWidthTicks) * width);
// Make sure width is at least 1px
left = Math.Min(left - 1, right);
left = Math.Min(left - 1, (int)graphRight);
// Skip rendering out of bounds bars
if (top < 0 || bottom > Height)
continue;
GL.Vertex2(left, bottom);
GL.Vertex2(left, top);
GL.Vertex2(graphRight, top);
GL.Vertex2(left, bottom);
GL.Vertex2(left, top);
GL.Vertex2(right, top);
GL.Vertex2(right, top);
GL.Vertex2(right, bottom);
GL.Vertex2(left, bottom);
GL.Vertex2(graphRight, top);
GL.Vertex2(graphRight, bottom);
GL.Vertex2(left, bottom);
}
verticalIndex++;
@ -120,7 +117,7 @@ namespace Ryujinx.Profiler.UI
// Dummy draw for measure
float labelWidth = _fontService.DrawText(label, 0, 0, LineHeight, false);
_fontService.DrawText(label, xOffset + width - labelWidth - LinePadding, FilterHeight + LinePadding, LineHeight);
_fontService.DrawText(label, graphRight - labelWidth - LinePadding, FilterHeight + LinePadding, LineHeight);
_fontService.DrawText($"-{MathF.Round((float)((timeWidthTicks / PerformanceCounter.TicksPerMillisecond) + _graphPosition), 2)} ms", xOffset + LinePadding, FilterHeight + LinePadding, LineHeight);
}