Files
2026-07-13 13:13:17 +08:00

87 lines
3.1 KiB
C#

#nullable enable
using T3.Core.Animation;
using T3.Core.DataTypes.DataSet;
using T3.Editor.Gui.UiHelpers;
namespace T3.Editor.App;
internal static class Profiling
{
internal static void KeepFrameData()
{
if (UserSettings.Config.EnableFrameProfiling)
{
_frameStartTime = Playback.RunTimeInSecs;
DebugDataRecording.StartRegion("__Stats/_ProcessFrame", null, ref _frameRegionChannel);
}
if (UserSettings.Config.EnableGCProfiling)
{
var gcMemoryInfo = GC.GetGCMemoryInfo();
TraceGCLevel(0, ref gcMemoryInfo);
TraceGCLevel(1, ref gcMemoryInfo);
TraceGCLevel(2, ref gcMemoryInfo);
}
}
internal static void EndFrameData()
{
if (!UserSettings.Config.EnableFrameProfiling || _frameRegionChannel == null)
return;
var frameEndTime = Playback.RunTimeInSecs;
var duration = frameEndTime - _frameStartTime;
DebugDataRecording.EndRegion(_frameRegionChannel, $"{duration * 1000:0ms}");
}
private static void TraceGCLevel(int level, ref GCMemoryInfo gcMemoryInfo)
{
var heapSizeBytes = gcMemoryInfo.GenerationInfo[level].SizeAfterBytes;
var lastHeapSizeBytes = _lastHeapSizeBytes[level];
if (heapSizeBytes == lastHeapSizeBytes)
return;
DebugDataRecording.KeepTraceData(_gcHeapSizePaths[level], heapSizeBytes, ref _gcHeapSizeChannels[level]);
DebugDataRecording.KeepTraceData(_gcHeapSizeDeltaPaths[level], heapSizeBytes - lastHeapSizeBytes, ref _gcHeapSizeDeltaChannels[level]);
_lastHeapSizeBytes[level] = heapSizeBytes;
}
private static readonly string[] _gcHeapSizePaths =
{
"__Stats/GC0-HeapSize",
"__Stats/GC1-HeapSize",
"__Stats/GC2-HeapSize",
"__Stats/GC3-HeapSize"
};
private static readonly string[] _gcHeapSizeDeltaPaths =
{
"__Stats/GC0-HeapSizeDelta",
"__Stats/GC1-HeapSizeDelta",
"__Stats/GC2-HeapSizeDelta",
"__Stats/GC3-HeapSizeDelta"
};
private const int MaxGCLevels = 4;
private static readonly DataChannel[] _gcHeapSizeChannels = new DataChannel[MaxGCLevels];
private static readonly DataChannel[] _gcHeapSizeDeltaChannels = new DataChannel[MaxGCLevels];
private static readonly long[] _lastHeapSizeBytes = new long[MaxGCLevels];
private static DataChannel? _frameRegionChannel; // Channels will be created on first use
private static double _frameStartTime;
public sealed class ProfilingLogWriterClass: ILogWriter
{
public void ProcessEntry(ILogEntry entry)
{
DebugDataRecording.KeepTraceData("__Stats/_Log", $"{entry.Level}: {entry.Message}", ref _logMessageChannel);
}
// TODO: Ths can probably be removed
public ILogEntry.EntryLevel Filter { get; set; }
public void Dispose() { }
private DataChannel? _logMessageChannel;
}
}