You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
731 lines
26 KiB
731 lines
26 KiB
using System.Collections.Generic;
|
|
using UnityEditor.Experimental;
|
|
using UnityEditor.Experimental.GraphView;
|
|
using UnityEngine;
|
|
using UnityEngine.Profiling;
|
|
using UnityEngine.VFX;
|
|
using UnityEngine.UIElements;
|
|
|
|
using PositionType = UnityEngine.UIElements.Position;
|
|
|
|
namespace UnityEditor.VFX.UI
|
|
{
|
|
class VFXProfilingBoard : GraphElement, IControlledElement<VFXViewController>, IVFXMovable, IVFXResizable
|
|
{
|
|
VFXViewController m_Controller;
|
|
Controller IControlledElement.controller
|
|
{
|
|
get { return m_Controller; }
|
|
}
|
|
public VFXViewController controller
|
|
{
|
|
get { return m_Controller; }
|
|
set
|
|
{
|
|
if (m_Controller != value)
|
|
{
|
|
if (m_Controller != null)
|
|
{
|
|
m_Controller.UnregisterHandler(this);
|
|
}
|
|
Clear();
|
|
m_Controller = value;
|
|
|
|
if (m_Controller != null)
|
|
{
|
|
m_Controller.RegisterHandler(this);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool hasExpandedPanel
|
|
{
|
|
get
|
|
{
|
|
foreach (var panel in m_AnchoredProfilerPanels)
|
|
{
|
|
if (!panel.isCollapsed)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
VFXView m_View;
|
|
IVisualElementScheduledItem m_UpdateItem;
|
|
IVisualElementScheduledItem m_TimingCollectionUpdateItem;
|
|
VisualEffect m_AttachedComponent;
|
|
private bool m_Enabled;
|
|
private bool m_SupportsGPURecorder;
|
|
|
|
private readonly int kDisplayUpdatePeriodMs = 300;
|
|
private readonly int kCollectUpdatePeriodMs = 10;
|
|
|
|
public VFXProfilingBoard(VFXView view)
|
|
{
|
|
m_View = view;
|
|
var tpl = VFXView.LoadUXML("VFXProfilingBoard");
|
|
|
|
tpl.CloneTree(contentContainer);
|
|
|
|
contentContainer.AddStyleSheetPath("VFXProfilingBoard");
|
|
|
|
m_RootElement = this.Query<VisualElement>("component-container");
|
|
m_SubtitleIcon = this.Query<Image>("subTitle-icon");
|
|
m_Subtitle = this.Query<Label>("subTitleLabel");
|
|
m_WarningIconTexture = EditorGUIUtility.LoadIcon(EditorResources.iconsPath + "console.warnicon.sml.png");
|
|
m_SubtitleIcon.image = m_WarningIconTexture;
|
|
m_GeneralInfoContainer = this.Query<VisualElement>("general-info-container");
|
|
m_CPUInfoContainer = this.Query<Foldout>("cpu-timings-foldout");
|
|
m_GPUInfoContainer = this.Query<Foldout>("gpu-timings-foldout");
|
|
m_HeatmapSettingsContainer = this.Query<Foldout>("heatmap-foldout");
|
|
m_TextureUsageFoldout = this.Query<Foldout>("texture-info-foldout");
|
|
m_TextureHashSet = new HashSet<Texture>();
|
|
m_TopExecutionTimeField = this.Query<FloatField>("exec-time");
|
|
|
|
m_TextureInfosLabelsPerSystem = new List<List<VFXContextProfilerUI.SlotLabel>>();
|
|
m_TextureSystemNameLabels = new List<Label>();
|
|
InitializeContextualMenu();
|
|
|
|
Detach();
|
|
this.AddManipulator(new Dragger { clampToParentEdges = true });
|
|
|
|
capabilities |= Capabilities.Movable;
|
|
|
|
RegisterCallback<MouseDownEvent>(OnMouseClick);
|
|
RegisterCallback<MouseUpEvent>(e=> e.StopPropagation());
|
|
// Prevent graphview from zooming in/out when using the mouse wheel over the component board
|
|
RegisterCallback<WheelEvent>(e => e.StopPropagation());
|
|
|
|
style.position = PositionType.Absolute;
|
|
|
|
SetPosition(BoardPreferenceHelper.LoadPosition(BoardPreferenceHelper.Board.profilingBoard, defaultRect));
|
|
|
|
m_SupportsGPURecorder = SystemInfo.supportsGpuRecorder;
|
|
SetupWarnings();
|
|
}
|
|
|
|
private void SetupWarnings()
|
|
{
|
|
if (!m_SupportsGPURecorder)
|
|
{
|
|
m_WarningGpuRecorder = new Label(VFXAnchoredProfilerUI.kGpuRecorderNotSupportedMsg);
|
|
m_GeneralInfoContainer.Add(m_WarningGpuRecorder);
|
|
}
|
|
m_WarningNoSystems = new Label("No valid system is running in this effect.");
|
|
m_GeneralInfoContainer.Add(m_WarningNoSystems);
|
|
m_WarningNoSystems.style.display = DisplayStyle.None;
|
|
}
|
|
private void InitializeContextualMenu()
|
|
{
|
|
m_ShortcutWindowButton = this.Query<Button>("shortcut-windows");
|
|
m_ShortcutWindowButton.focusable = false;
|
|
|
|
m_ShortcutWindowMenu = new GenericMenu();
|
|
m_ShortcutWindowMenu.AddItem(new GUIContent("Open Profiler Window"), false,
|
|
() => EditorApplication.ExecuteMenuItem("Window/Analysis/Profiler"));
|
|
m_ShortcutWindowMenu.AddItem(new GUIContent("Open Rendering Debugger"), false, () =>
|
|
{
|
|
EditorApplication.ExecuteMenuItem("Window/Analysis/Rendering Debugger");
|
|
});
|
|
|
|
m_ShortcutWindowButton.clickable.clicked += () => { m_ShortcutWindowMenu.ShowAsContext(); };
|
|
}
|
|
|
|
internal void TogglePanelsVisibility()
|
|
{
|
|
bool? expand = null;
|
|
foreach (var panel in m_AnchoredProfilerPanels)
|
|
{
|
|
expand ??= panel.isCollapsed;
|
|
if (expand.Value) panel.ForceExpand();
|
|
else panel.ForceClose();
|
|
}
|
|
}
|
|
|
|
public void ValidatePosition()
|
|
{
|
|
BoardPreferenceHelper.ValidatePosition(this, m_View, defaultRect);
|
|
}
|
|
|
|
static readonly Rect defaultRect = new Rect(200, 100, 300, 300);
|
|
|
|
public override Rect GetPosition()
|
|
{
|
|
return new Rect(resolvedStyle.left, resolvedStyle.top, resolvedStyle.width, resolvedStyle.height);
|
|
}
|
|
|
|
public override void SetPosition(Rect newPos)
|
|
{
|
|
style.left = newPos.xMin;
|
|
style.top = newPos.yMin;
|
|
style.width = newPos.width;
|
|
style.height = newPos.height;
|
|
}
|
|
|
|
void OnMouseClick(MouseDownEvent e)
|
|
{
|
|
m_View.SetBoardToFront(this);
|
|
e.StopPropagation();
|
|
}
|
|
|
|
public void Detach()
|
|
{
|
|
m_RootElement.SetEnabled(false);
|
|
m_Subtitle.text = "Select a Game Object running this VFX";
|
|
m_SubtitleIcon.style.display = DisplayStyle.Flex;
|
|
|
|
if (m_AttachedComponent != null)
|
|
{
|
|
m_AttachedComponent.UnregisterForProfiling();
|
|
}
|
|
m_AttachedComponent = null;
|
|
|
|
PauseUpdateItems();
|
|
|
|
DisableProfilerPanels();
|
|
m_CPUInfoContainer.Clear();
|
|
m_GPUInfoContainer.Clear();
|
|
m_HeatmapSettingsContainer.Clear();
|
|
m_TextureUsageFoldout.Clear();
|
|
}
|
|
|
|
private void PauseUpdateItems()
|
|
{
|
|
if (m_UpdateItem != null)
|
|
{
|
|
m_UpdateItem.Pause();
|
|
}
|
|
|
|
if (m_TimingCollectionUpdateItem != null)
|
|
{
|
|
m_TimingCollectionUpdateItem.Pause();
|
|
}
|
|
}
|
|
|
|
private bool IsValidEffect()
|
|
{
|
|
bool valid = false;
|
|
foreach (var systemController in m_View.controller.systems)
|
|
{
|
|
if (systemController.contexts[0].model.CanBeCompiled())
|
|
{
|
|
valid = true;
|
|
break;
|
|
}
|
|
}
|
|
return valid;
|
|
}
|
|
|
|
private void ClearUI()
|
|
{
|
|
if (m_AnchoredProfilerPanels != null)
|
|
{
|
|
foreach (var anchoredPanel in m_AnchoredProfilerPanels)
|
|
{
|
|
anchoredPanel.Detach();
|
|
}
|
|
m_AnchoredProfilerPanels.Clear();
|
|
}
|
|
m_CPUInfoContainer.Clear();
|
|
m_GPUInfoContainer.Clear();
|
|
m_TextureUsageFoldout.Clear();
|
|
m_HeatmapSettingsContainer.Clear();
|
|
}
|
|
private void SetupUI()
|
|
{
|
|
if (!IsValidEffect())
|
|
{
|
|
ClearUI();
|
|
m_WarningNoSystems.style.display = DisplayStyle.Flex;
|
|
return;
|
|
}
|
|
m_WarningNoSystems.style.display = DisplayStyle.None;
|
|
|
|
SetupCpuData();
|
|
SetupGpuData();
|
|
SetupHeatMapSettings();
|
|
CreateOrResumeUpdateItems();
|
|
EnableProfilerPanels();
|
|
SetupTextureUsageSection();
|
|
UpdateDynamicValues();
|
|
}
|
|
|
|
public bool Attach(VisualEffect effect)
|
|
{
|
|
VisualEffect target = effect != null ? effect : Selection.activeGameObject?.GetComponent<VisualEffect>();
|
|
if (target != null && m_View.controller?.graph != null && m_AttachedComponent != target)
|
|
{
|
|
if (m_AttachedComponent != null)
|
|
{
|
|
m_AttachedComponent.UnregisterForProfiling();
|
|
}
|
|
|
|
m_AttachedComponent = target;
|
|
if (m_Enabled)
|
|
{
|
|
m_AttachedComponent.RegisterForProfiling();
|
|
SetupUI();
|
|
}
|
|
|
|
m_Subtitle.text = m_AttachedComponent.name;
|
|
|
|
m_RootElement.SetEnabled(true);
|
|
m_SubtitleIcon.style.display = DisplayStyle.None;
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public void Enable()
|
|
{
|
|
m_Enabled = true;
|
|
BoardPreferenceHelper.SetVisible(BoardPreferenceHelper.Board.profilingBoard, true);
|
|
if (m_AttachedComponent != null)
|
|
{
|
|
m_AttachedComponent.RegisterForProfiling();
|
|
SetupUI();
|
|
}
|
|
}
|
|
|
|
public void Disable()
|
|
{
|
|
m_Enabled = false;
|
|
RemoveFromHierarchy();
|
|
BoardPreferenceHelper.SetVisible(BoardPreferenceHelper.Board.profilingBoard, false);
|
|
DisableProfilerPanels();
|
|
if (m_AttachedComponent != null)
|
|
{
|
|
m_AttachedComponent.UnregisterForProfiling();
|
|
}
|
|
}
|
|
|
|
public void EnableProfilerPanels()
|
|
{
|
|
if (m_AnchoredProfilerPanels != null)
|
|
{
|
|
foreach (var anchoredPanel in m_AnchoredProfilerPanels)
|
|
{
|
|
anchoredPanel.Detach();
|
|
}
|
|
m_AnchoredProfilerPanels.Clear();
|
|
}
|
|
else
|
|
{
|
|
m_AnchoredProfilerPanels = new List<VFXAnchoredProfilerUI>();
|
|
m_ContextsUIToContextPanel = new Dictionary<VFXContextUI, VFXContextProfilerUI>();
|
|
}
|
|
|
|
List<VFXContextProfilerUI> systemContexts = new List<VFXContextProfilerUI>();
|
|
foreach (var systemBorder in m_View.systems)
|
|
{
|
|
if(systemBorder.contexts.Length == 0 || !systemBorder.contexts[0].controller.model.GetData().CanBeCompiled())
|
|
continue;
|
|
VFXContextUI initContextUI = null;
|
|
foreach(var contextUI in systemBorder.contexts)
|
|
{
|
|
if((contextUI.controller.model.contextType & VFXContextType.InitAndUpdateAndOutput) != 0)
|
|
{
|
|
VFXContextProfilerUI contextPanel;
|
|
if (m_ContextsUIToContextPanel.TryGetValue(contextUI, out contextPanel))
|
|
contextPanel.AnchorTo(contextUI);
|
|
else
|
|
contextPanel = new VFXContextProfilerUI(contextUI);
|
|
|
|
contextPanel.attachedComponent = m_AttachedComponent;
|
|
m_AnchoredProfilerPanels.Add(contextPanel);
|
|
systemContexts.Add(contextPanel);
|
|
}
|
|
|
|
if (contextUI.controller.model.contextType == VFXContextType.Init)
|
|
initContextUI = contextUI;
|
|
}
|
|
var systemPanel = new VFXSystemProfilerUI(initContextUI, systemContexts);
|
|
systemContexts.Clear();
|
|
systemPanel.attachedComponent = m_AttachedComponent;
|
|
m_AnchoredProfilerPanels.Add(systemPanel);
|
|
}
|
|
|
|
//Add spawners contexts
|
|
var contextUIs = m_View.GetAllContexts();
|
|
foreach (var contextUI in contextUIs)
|
|
{
|
|
if (contextUI.controller.model.contextType == VFXContextType.Spawner)
|
|
{
|
|
var contextPanel = new VFXContextProfilerUI(contextUI);
|
|
contextPanel.attachedComponent = m_AttachedComponent;
|
|
m_AnchoredProfilerPanels.Add(contextPanel);
|
|
}
|
|
}
|
|
m_ContextsUIToContextPanel.Clear();
|
|
foreach (var anchoredPanel in m_AnchoredProfilerPanels)
|
|
{
|
|
if(anchoredPanel is VFXContextProfilerUI contextPanel)
|
|
m_ContextsUIToContextPanel.Add(contextPanel.contextUI, contextPanel);
|
|
}
|
|
}
|
|
|
|
public void DisableProfilerPanels()
|
|
{
|
|
if (m_AnchoredProfilerPanels != null)
|
|
{
|
|
foreach (var anchoredPanel in m_AnchoredProfilerPanels)
|
|
anchoredPanel.Detach();
|
|
m_AnchoredProfilerPanels.Clear();
|
|
}
|
|
}
|
|
|
|
private void CreateOrResumeUpdateItems()
|
|
{
|
|
if (m_UpdateItem == null)
|
|
m_UpdateItem = schedule.Execute(Update).Every(kDisplayUpdatePeriodMs);
|
|
else
|
|
m_UpdateItem.Resume();
|
|
|
|
if (m_TimingCollectionUpdateItem == null)
|
|
m_TimingCollectionUpdateItem = schedule.Execute(CollectStats).Every(kCollectUpdatePeriodMs);
|
|
else
|
|
m_TimingCollectionUpdateItem.Resume();
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (m_AttachedComponent == null)
|
|
{
|
|
Detach();
|
|
return;
|
|
}
|
|
|
|
if (m_Enabled)
|
|
{
|
|
if(!m_AttachedComponent.IsRegisteredForProfiling() && IsValidEffect())
|
|
m_AttachedComponent.RegisterForProfiling();
|
|
UpdateDynamicValues();
|
|
}
|
|
|
|
string path = m_AttachedComponent.name;
|
|
|
|
UnityEngine.Transform current = m_AttachedComponent.transform.parent;
|
|
while (current != null)
|
|
{
|
|
path = current.name + " > " + path;
|
|
current = current.parent;
|
|
}
|
|
|
|
if (UnityEngine.SceneManagement.SceneManager.loadedSceneCount > 1)
|
|
{
|
|
path = m_AttachedComponent.gameObject.scene.name + " : " + path;
|
|
}
|
|
|
|
if (m_Subtitle.text != path)
|
|
m_Subtitle.text = path;
|
|
}
|
|
|
|
|
|
|
|
public class ProfilingItemLeaf
|
|
{
|
|
public ProfilingItemLeaf(Recorder recorder, Label label)
|
|
{
|
|
this.recorder = recorder;
|
|
this.label = label;
|
|
maxTiming = 0;
|
|
minTiming = 0;
|
|
average = 0;
|
|
}
|
|
long LongMax(long a, long b)
|
|
{
|
|
return a > b ? a : b;
|
|
}
|
|
long LongMin(long a, long b)
|
|
{
|
|
return a <= b ? a : b;
|
|
}
|
|
public void UpdateTimingStats(long time)
|
|
{
|
|
maxTiming = LongMax(maxTiming, time);
|
|
minTiming = LongMin(minTiming, time);
|
|
average = (long)(kAverageAlpha * average) + (long)((1.0f - kAverageAlpha) * time);
|
|
}
|
|
public void ResetTimingStats()
|
|
{
|
|
maxTiming = 0;
|
|
minTiming = long.MaxValue;
|
|
}
|
|
public Recorder recorder;
|
|
public Label label;
|
|
public long maxTiming;
|
|
public long minTiming;
|
|
public long average;
|
|
private const float kAverageAlpha = 0.9f;
|
|
|
|
}
|
|
|
|
List<ProfilingItemLeaf> m_CpuProfilingItemLeaves;
|
|
|
|
void SetupCpuData()
|
|
{
|
|
m_CPUInfoContainer.Clear();
|
|
if(m_CpuProfilingItemLeaves != null)
|
|
m_CpuProfilingItemLeaves.Clear();
|
|
else
|
|
m_CpuProfilingItemLeaves = new List<ProfilingItemLeaf>();
|
|
|
|
AddEffectCpuLeaf(VisualEffect.VFXCPUEffectMarkers.FullUpdate, "Full Update", "Update time of the entire effect on the CPU.");
|
|
//AddEffectCpuLeaf(CPUMarkers.ProcessUpdate, " Process Update");
|
|
AddEffectCpuLeaf(VisualEffect.VFXCPUEffectMarkers.EvaluateExpressions, " Evaluate Expressions", "");
|
|
List<string> systemNamesFromAsset = new List<string>();
|
|
m_View.controller.graph.visualEffectResource.asset.GetParticleSystemNames(systemNamesFromAsset);
|
|
foreach (var systemName in systemNamesFromAsset)
|
|
{
|
|
AddSystemCpuLeaf(systemName);
|
|
}
|
|
}
|
|
|
|
void SetupGpuData()
|
|
{
|
|
m_GPUInfoContainer.Clear();
|
|
m_GPUTimeLabel = AddDataRowWithDynamicLabel(m_GPUInfoContainer, "GPU time");
|
|
m_GPUTimeLabel.tooltip = "Execution time of the system on the GPU";
|
|
if (!m_SupportsGPURecorder)
|
|
{
|
|
m_GPUTimeLabel.text = "-";
|
|
m_GPUInfoContainer.tooltip = VFXAnchoredProfilerUI.kGpuRecorderNotSupportedMsg;
|
|
}
|
|
m_GPUMemoryLabel = AddDataRowWithDynamicLabel(m_GPUInfoContainer, "GPU memory");
|
|
m_GPUMemoryLabel.tooltip = "GPU Memory usage of the entire effect.";
|
|
}
|
|
|
|
void SetupHeatMapSettings()
|
|
{
|
|
m_HeatmapSettingsContainer.Clear();
|
|
m_TopExecutionTimeField = new FloatField("GPU Time Threshold (ms)")
|
|
{
|
|
name = "exec-time",
|
|
tooltip = "Heatmap for visual feedback for execution time values in the graph, using a color gradient. Controls the value above which the timings will be red.",
|
|
value = 0.1f,
|
|
};
|
|
|
|
m_HeatmapSettingsContainer.Add(m_TopExecutionTimeField);
|
|
m_TopExecutionTimeField.RegisterValueChangedCallback(evt =>
|
|
{
|
|
foreach (var anchoredPanel in m_AnchoredProfilerPanels)
|
|
{
|
|
anchoredPanel.SetHeatmapRefValue(evt.newValue);
|
|
}
|
|
});
|
|
}
|
|
|
|
void SetupTextureUsageSection()
|
|
{
|
|
if(m_TextureUsageFoldout != null)
|
|
{
|
|
m_TextureInfosLabelsPerSystem.Clear();
|
|
m_TextureUsageFoldout.Clear();
|
|
m_TextureSystemNameLabels.Clear();
|
|
foreach (var anchoredPanel in m_AnchoredProfilerPanels)
|
|
{
|
|
if (anchoredPanel is VFXSystemProfilerUI systemPanel)
|
|
{
|
|
var systemNameLabel = new Label(systemPanel.GetSystemName());
|
|
m_TextureSystemNameLabels.Add(systemNameLabel);
|
|
m_TextureUsageFoldout.Add(systemNameLabel);
|
|
m_TextureInfosLabelsPerSystem.Add(new List<VFXContextProfilerUI.SlotLabel>());
|
|
foreach (var textureSlot in systemPanel.GetTextureSlotsFromContexts())
|
|
{
|
|
var slotLabelGlobal = new VFXContextProfilerUI.SlotLabel(textureSlot, null);
|
|
m_TextureInfosLabelsPerSystem[^1].Add(slotLabelGlobal);
|
|
m_TextureUsageFoldout.Add(slotLabelGlobal.label);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Label AddDataRowWithDynamicLabel(VisualElement container, string labelText)
|
|
{
|
|
var labelContainer = new VisualElement();
|
|
labelContainer.AddToClassList("dynamic-label");
|
|
var mainLabel = new Label(labelText);
|
|
mainLabel.AddToClassList("main");
|
|
var dynamicLabel = new Label();
|
|
dynamicLabel.AddToClassList("dynamic");
|
|
labelContainer.Add(mainLabel);
|
|
labelContainer.Add(dynamicLabel);
|
|
container.Add(labelContainer);
|
|
|
|
return dynamicLabel;
|
|
}
|
|
|
|
void AddEffectCpuLeaf(VisualEffect.VFXCPUEffectMarkers markerType, string displayName, string tooltip)
|
|
{
|
|
var markerName = m_AttachedComponent.GetCPUEffectMarkerName(markerType);
|
|
var recorder = Recorder.Get(markerName);
|
|
Label timingLabel = AddDataRowWithDynamicLabel(m_CPUInfoContainer, displayName);
|
|
timingLabel.tooltip = tooltip;
|
|
ProfilingItemLeaf leaf = new ProfilingItemLeaf(recorder, timingLabel);
|
|
m_CpuProfilingItemLeaves.Add(leaf);
|
|
}
|
|
|
|
void AddSystemCpuLeaf(string systemName)
|
|
{
|
|
var markerName = m_AttachedComponent.GetCPUSystemMarkerName(systemName);
|
|
var recorder = Recorder.Get(markerName);
|
|
Label timingLabel = AddDataRowWithDynamicLabel(m_CPUInfoContainer, systemName);
|
|
ProfilingItemLeaf leaf = new ProfilingItemLeaf(recorder, timingLabel);
|
|
m_CpuProfilingItemLeaves.Add(leaf);
|
|
}
|
|
|
|
public long GetEffectAggregatedGPUTime()
|
|
{
|
|
long aggregate = 0L;
|
|
foreach (var contextPanel in m_AnchoredProfilerPanels)
|
|
{
|
|
if(contextPanel is VFXSystemProfilerUI systemPanel)
|
|
aggregate += systemPanel.GetSystemAggregatedGPUTime();
|
|
}
|
|
return aggregate;
|
|
}
|
|
|
|
void UpdateDynamicValues()
|
|
{
|
|
const float kNanoToMilli = 1e-6f;
|
|
|
|
foreach (var anchoredPanel in m_AnchoredProfilerPanels)
|
|
{
|
|
anchoredPanel.UpdateDynamicValues();
|
|
}
|
|
|
|
foreach (var leaf in m_CpuProfilingItemLeaves)
|
|
{
|
|
var timingLabel = leaf.label;
|
|
if (timingLabel != null)
|
|
{
|
|
timingLabel.text = $"{(leaf.average * kNanoToMilli):F3} ms";
|
|
}
|
|
leaf.ResetTimingStats();
|
|
}
|
|
|
|
if (m_GPUMemoryLabel != null & m_GPUTimeLabel != null)
|
|
{
|
|
var batchInfo = UnityEngine.VFX.VFXManager.GetBatchedEffectInfo(m_AttachedComponent.visualEffectAsset);
|
|
|
|
m_GPUMemoryLabel.text = $"{ EditorUtility.FormatBytes((long)batchInfo.totalGPUSizeInBytes / batchInfo.totalInstanceCapacity)}";
|
|
if(m_SupportsGPURecorder)
|
|
m_GPUTimeLabel.text = $"{GetEffectAggregatedGPUTime() * kNanoToMilli:F3} ms";
|
|
}
|
|
|
|
for (int i = 0; i < m_TextureSystemNameLabels.Count; i++)
|
|
{
|
|
var systemSlotLabel = m_TextureInfosLabelsPerSystem[i];
|
|
m_TextureHashSet.Clear();
|
|
foreach (var slotLabel in systemSlotLabel)
|
|
{
|
|
Texture texture = slotLabel.slot.value as Texture;
|
|
if (m_TextureHashSet.Contains(texture) || texture == null)
|
|
{
|
|
slotLabel.label.style.display = DisplayStyle.None;
|
|
continue;
|
|
}
|
|
|
|
slotLabel.label.style.display = DisplayStyle.Flex;
|
|
string textureLabelText = VFXContextProfilerUI.GetTextureInformationString(texture);
|
|
m_TextureHashSet.Add(texture);
|
|
if (slotLabel.label.text != textureLabelText)
|
|
{
|
|
slotLabel.label.text = $" {textureLabelText}";
|
|
}
|
|
}
|
|
m_TextureSystemNameLabels[i].style.display = m_TextureHashSet.Count == 0 ? DisplayStyle.None : DisplayStyle.Flex;
|
|
}
|
|
|
|
}
|
|
|
|
void CollectStats()
|
|
{
|
|
bool hasVfxUpdate = true;
|
|
foreach (var leaf in m_CpuProfilingItemLeaves)
|
|
{
|
|
if (leaf.recorder.sampleBlockCount == 0)
|
|
{
|
|
hasVfxUpdate = false;
|
|
break;
|
|
}
|
|
leaf.UpdateTimingStats(leaf.recorder.elapsedNanoseconds);
|
|
}
|
|
|
|
if (hasVfxUpdate)
|
|
{
|
|
foreach (var anchoredPanel in m_AnchoredProfilerPanels)
|
|
anchoredPanel.CollectStats();
|
|
}
|
|
}
|
|
|
|
Button m_ShortcutWindowButton;
|
|
GenericMenu m_ShortcutWindowMenu;
|
|
|
|
VisualElement m_RootElement;
|
|
VisualElement m_CPUInfoContainer;
|
|
VisualElement m_GPUInfoContainer;
|
|
VisualElement m_HeatmapSettingsContainer;
|
|
VisualElement m_TextureUsageFoldout;
|
|
VisualElement m_GeneralInfoContainer;
|
|
|
|
private List<Label> m_TextureSystemNameLabels;
|
|
private List<List<VFXContextProfilerUI.SlotLabel>> m_TextureInfosLabelsPerSystem;
|
|
|
|
HashSet<Texture> m_TextureHashSet;
|
|
FloatField m_TopExecutionTimeField;
|
|
Label m_GPUTimeLabel;
|
|
Label m_GPUMemoryLabel;
|
|
Label m_Subtitle;
|
|
Image m_SubtitleIcon;
|
|
Texture2D m_WarningIconTexture;
|
|
VisualElement m_WarningGpuRecorder;
|
|
VisualElement m_WarningNoSystems;
|
|
|
|
private List<VFXAnchoredProfilerUI> m_AnchoredProfilerPanels;
|
|
private Dictionary<VFXContextUI, VFXContextProfilerUI> m_ContextsUIToContextPanel;
|
|
|
|
public new void Clear()
|
|
{
|
|
Detach();
|
|
}
|
|
|
|
void IControlledElement.OnControllerChanged(ref ControllerChangedEvent e)
|
|
{
|
|
if (e.change != VFXViewController.Change.ui)
|
|
{
|
|
if (m_AttachedComponent != null)
|
|
{
|
|
if (m_Enabled)
|
|
{
|
|
m_AttachedComponent.RegisterForProfiling();
|
|
SetupUI();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void UpdatePresenterPosition()
|
|
{
|
|
BoardPreferenceHelper.SavePosition(BoardPreferenceHelper.Board.profilingBoard, GetPosition());
|
|
}
|
|
|
|
public void OnMoved()
|
|
{
|
|
BoardPreferenceHelper.SavePosition(BoardPreferenceHelper.Board.profilingBoard, GetPosition());
|
|
}
|
|
|
|
void IVFXResizable.OnStartResize() { }
|
|
public void OnResized()
|
|
{
|
|
BoardPreferenceHelper.SavePosition(BoardPreferenceHelper.Board.profilingBoard, GetPosition());
|
|
}
|
|
}
|
|
|
|
}
|