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:
parent
aef7582888
commit
5a3cac991c
1 changed files with 34 additions and 37 deletions
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue