// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic;
using FlaxEditor.GUI;
using FlaxEditor.GUI.Tabs;
using FlaxEngine;
namespace FlaxEditor.Windows.Profiler
{
///
/// Base class for all profiler modes. Implementation collects profiling events and presents it using dedicated UI.
///
public class ProfilerMode : Tab
{
///
/// The shared data container for the profiler modes. Used to reduce calls to profiler tool backend for the same data across different profiler fronted modes.
///
public struct SharedUpdateData
{
private ProfilingTools.ThreadStats[] _cpuEvents;
private ProfilerGPU.Event[] _gpuEvents;
///
/// The main stats. Gathered by auto by profiler before profiler mode update.
///
public ProfilingTools.MainStats Stats;
///
/// The additional managed memory allocation size during this update. Given value is in bytes.
///
public int ManagedMemoryAllocation;
///
/// Gets the collected CPU events by the profiler from local or remote session.
///
/// Buffer with events per thread.
public ProfilingTools.ThreadStats[] GetEventsCPU()
{
return _cpuEvents ?? (_cpuEvents = ProfilingTools.EventsCPU);
}
///
/// Gets the collected GPU events by the profiler from local or remote session.
///
/// Buffer with rendering events.
public ProfilerGPU.Event[] GetEventsGPU()
{
return _gpuEvents ?? (_gpuEvents = ProfilingTools.EventsGPU);
}
///
/// Begins the data usage. Prepares the container.
///
public void Begin()
{
Stats = ProfilingTools.Stats;
_cpuEvents = null;
_gpuEvents = null;
}
///
/// Ends the data usage. Cleanups the container.
///
public void End()
{
_cpuEvents = null;
_gpuEvents = null;
}
}
///
/// The maximum amount of samples to collect.
///
public const int MaxSamples = 60 * 10;
///
/// The minimum event time in ms.
///
public const double MinEventTimeMs = 0.000000001;
///
/// Occurs when selected sample gets changed. Profiling window should propagate this change to all charts and view modes.
///
public event Action SelectedSampleChanged;
///
public ProfilerMode(string text)
: base(text)
{
}
///
public override void OnDestroy()
{
Clear();
base.OnDestroy();
}
///
/// Initializes this instance.
///
public virtual void Init()
{
}
///
/// Clears this instance.
///
public virtual void Clear()
{
}
///
/// Updates this instance. Called every frame if live recording is enabled.
///
/// The shared data.
public virtual void Update(ref SharedUpdateData sharedData)
{
}
///
/// Updates the mode view. Called after init and on selected frame changed.
///
/// The selected frame index.
/// True if show only events that happened during the last engine update (excluding events from fixed update or draw event), otherwise show all collected events.
public virtual void UpdateView(int selectedFrame, bool showOnlyLastUpdateEvents)
{
}
///
/// Called when selected sample gets changed.
///
/// Index of the view frame.
protected virtual void OnSelectedSampleChanged(int frameIndex)
{
SelectedSampleChanged?.Invoke(frameIndex);
}
///
/// Recycles all table rows to be reused.
///
/// The table.
/// The output cache.
protected static void RecycleTableRows(Table table, List rowsCache)
{
int idx = 0;
while (table.Children.Count > idx)
{
var child = table.Children[idx];
if (child is Row row)
{
rowsCache.Add(row);
child.Parent = null;
}
else
{
idx++;
}
}
}
}
}