您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

237 行
10 KiB

using UnityEditor;
using UnityEditorInternal;
using System.Reflection;
using System;
using UnityEngine;
using System.Collections.Generic;
namespace ProfileAnalyser
{
public class ProfilerWindowInterface
{
private Type m_profilerWindowType;
private EditorWindow m_profilerWindow;
private FieldInfo m_currentFrameFieldInfo;
private FieldInfo m_timeLineGUIFieldInfo;
private FieldInfo m_selectedEntryFieldInfo;
private FieldInfo m_selectedNameFieldInfo;
private FieldInfo m_selectedTimeFieldInfo;
private FieldInfo m_selectedDurationFieldInfo;
private FieldInfo m_selectedInstanceIdFieldInfo;
private FieldInfo m_selectedInstanceCountFieldInfo;
private FieldInfo m_selectedFrameIdFieldInfo;
private FieldInfo m_selectedThreadIdFieldInfo;
private FieldInfo m_selectedNativeIndexFieldInfo;
public ProfilerWindowInterface()
{
Assembly assem = typeof(Editor).Assembly;
m_profilerWindowType = assem.GetType("UnityEditor.ProfilerWindow");
m_currentFrameFieldInfo = m_profilerWindowType.GetField("m_CurrentFrame", BindingFlags.NonPublic | BindingFlags.Instance);
m_timeLineGUIFieldInfo = m_profilerWindowType.GetField("m_CPUTimelineGUI", BindingFlags.NonPublic | BindingFlags.Instance);
if (m_timeLineGUIFieldInfo != null)
m_selectedEntryFieldInfo = m_timeLineGUIFieldInfo.FieldType.GetField("m_SelectedEntry", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
if (m_selectedEntryFieldInfo != null)
{
m_selectedNameFieldInfo = m_selectedEntryFieldInfo.FieldType.GetField("name", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
m_selectedTimeFieldInfo = m_selectedEntryFieldInfo.FieldType.GetField("time", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
m_selectedDurationFieldInfo = m_selectedEntryFieldInfo.FieldType.GetField("duration", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
m_selectedInstanceIdFieldInfo = m_selectedEntryFieldInfo.FieldType.GetField("instanceId", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
m_selectedInstanceCountFieldInfo = m_selectedEntryFieldInfo.FieldType.GetField("instanceCount", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
m_selectedFrameIdFieldInfo = m_selectedEntryFieldInfo.FieldType.GetField("frameId", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
m_selectedThreadIdFieldInfo = m_selectedEntryFieldInfo.FieldType.GetField("threadId", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
m_selectedNativeIndexFieldInfo = m_selectedEntryFieldInfo.FieldType.GetField("nativeIndex", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
}
}
/*
public EditorWindow GetProfileWindow()
{
return m_profilerWindow;
}
*/
public bool IsReady()
{
if (m_profilerWindow != null)
return true;
return false;
}
public bool IsProfilerWindowOpen()
{
UnityEngine.Object[] windows = Resources.FindObjectsOfTypeAll(m_profilerWindowType);
if (windows != null && windows.Length > 0)
return true;
return false;
}
public void OpenProfilerOrUseExisting()
{
m_profilerWindow = EditorWindow.GetWindow(m_profilerWindowType);
}
public bool GetFrameRangeFromProfiler(out int first, out int last)
{
if (m_profilerWindow)
//if (ProfilerDriver.enabled)
{
first = 1 + ProfilerDriver.firstFrameIndex;
last = 1 + ProfilerDriver.lastFrameIndex;
return true;
}
first = 1;
last = 1;
return false;
}
public void CloseProfiler()
{
if (m_profilerWindow)
m_profilerWindow.Close();
}
public string GetProfilerWindowMarkerName()
{
var timeLineGUI = m_timeLineGUIFieldInfo.GetValue(m_profilerWindow);
if (timeLineGUI != null && m_selectedEntryFieldInfo != null)
{
var selectedEntry = m_selectedEntryFieldInfo.GetValue(timeLineGUI);
if (selectedEntry != null && m_selectedNameFieldInfo != null)
{
return m_selectedNameFieldInfo.GetValue(selectedEntry).ToString();
}
}
return null;
}
public float GetFrameTime(int frameIndex)
{
ProfilerFrameDataIterator frameData = new ProfilerFrameDataIterator();
frameData.SetRoot(frameIndex, 0);
float ms = frameData.frameTimeMS;
frameData.Dispose();
return ms;
}
private bool GetMarkerInfo(string markerName, int frameIndex, string threadFilter, out int outThreadIndex, out float time, out float duration, out int instanceId)
{
ProfilerFrameDataIterator frameData = new ProfilerFrameDataIterator();
outThreadIndex = 0;
time = 0.0f;
duration = 0.0f;
instanceId = 0;
bool found = false;
int threadCount = frameData.GetThreadCount(frameIndex);
Dictionary<string, int> threadNameCount = new Dictionary<string, int>();
for (int threadIndex = 0; threadIndex < threadCount; ++threadIndex)
{
frameData.SetRoot(frameIndex, threadIndex);
var threadName = frameData.GetThreadName();
if (!threadNameCount.ContainsKey(threadName))
threadNameCount.Add(threadName, 1);
else
threadNameCount[threadName] += 1;
var threadNameWithIndex = ProfileData.ThreadNameWithIndex(threadNameCount[threadName], threadName);
if (threadFilter == "All" || threadNameWithIndex == threadFilter)
{
const bool enterChildren = true;
while (frameData.Next(enterChildren))
{
if (frameData.name == markerName)
{
time = frameData.startTimeMS;
duration = frameData.durationMS;
instanceId = frameData.instanceId;
outThreadIndex = threadIndex;
found = true;
break;
}
}
}
if (found)
break;
}
frameData.Dispose();
return found;
}
public void SetProfilerWindowMarkerName(string markerName, string threadFilter)
{
if (m_profilerWindow == null)
return;
var timeLineGUI = m_timeLineGUIFieldInfo.GetValue(m_profilerWindow);
if (timeLineGUI != null && m_selectedEntryFieldInfo != null)
{
var selectedEntry = m_selectedEntryFieldInfo.GetValue(timeLineGUI);
if (selectedEntry != null)
{
// Read profiler data direct from profile to find time/duration
int currentFrameIndex = (int)m_currentFrameFieldInfo.GetValue(m_profilerWindow);
float time;
float duration;
int instanceId;
int threadIndex;
if (GetMarkerInfo(markerName, currentFrameIndex, threadFilter, out threadIndex, out time, out duration, out instanceId))
{
/*
Debug.Log(string.Format("Setting profiler to {0} on {1} at frame {2} at {3}ms for {4}ms ({5})",
markerName, currentFrameIndex, threadFilter, time, duration, instanceId));
*/
if (m_selectedNameFieldInfo != null)
m_selectedNameFieldInfo.SetValue(selectedEntry, markerName);
if (m_selectedTimeFieldInfo != null)
m_selectedTimeFieldInfo.SetValue(selectedEntry, time);
if (m_selectedDurationFieldInfo != null)
m_selectedDurationFieldInfo.SetValue(selectedEntry, duration);
if (m_selectedInstanceIdFieldInfo != null)
m_selectedInstanceIdFieldInfo.SetValue(selectedEntry, instanceId);
if (m_selectedFrameIdFieldInfo != null)
m_selectedFrameIdFieldInfo.SetValue(selectedEntry, currentFrameIndex);
if (m_selectedThreadIdFieldInfo != null)
m_selectedThreadIdFieldInfo.SetValue(selectedEntry, threadIndex);
// TODO : Update to fill in the total and number of instances.
// For now we force Instance count to 1 to avoid the incorrect info showing.
if (m_selectedInstanceCountFieldInfo != null)
m_selectedInstanceCountFieldInfo.SetValue(selectedEntry, 1);
// Set other values to non negative values so selection appears
if (m_selectedNativeIndexFieldInfo != null)
m_selectedNativeIndexFieldInfo.SetValue(selectedEntry, currentFrameIndex);
m_profilerWindow.Repaint();
}
}
}
}
public bool JumpToFrame(int index)
{
//if (!ProfilerDriver.enabled)
// return;
if (!m_profilerWindow)
return false;
m_currentFrameFieldInfo.SetValue(m_profilerWindow, index - 1);
m_profilerWindow.Repaint();
return true;
}
}
}