int GetItemIdFromRawFrameDataIndexPath(HierarchyFrameDataView m_FrameDataView, List <int> deepestRawSampleIndexPathFound, out int foundDepth, out bool selectedItemsPathIsExpanded) { selectedItemsPathIsExpanded = true; var newSelectedId = m_FrameDataView.GetRootItemID(); var deepestPath = deepestRawSampleIndexPathFound.Count; for (int markerDepth = 0; markerDepth < deepestPath; markerDepth++) { var oldSelectedId = newSelectedId; if (m_FrameDataView.HasItemChildren(newSelectedId)) { // TODO: maybe HierarchyFrameDataView should just have a method GetChildItemByRawFrameDataViewIndex to avoid this List<int> marshalling need... m_FrameDataView.GetItemChildren(newSelectedId, m_ReusableChildrenIds); for (int i = 0; i < m_ReusableChildrenIds.Count; i++) { var childId = m_ReusableChildrenIds[i]; if (m_FrameDataView.ItemContainsRawFrameDataViewIndex(childId, deepestRawSampleIndexPathFound[markerDepth])) { // check if the parent is expanded if (selectedItemsPathIsExpanded && !IsExpanded(newSelectedId)) { selectedItemsPathIsExpanded = false; } newSelectedId = childId; break; } } } if (oldSelectedId == newSelectedId) { // there was no fitting sample in this scope so the path has been cut short here deepestPath = markerDepth; break; } } foundDepth = deepestPath; return(newSelectedId); }
private static int GetItemIdMatchingRecursive(HierarchyFrameDataView frameData, int itemId, Func <string, bool> predicate) { string searchString = ""; var functionName = frameData.GetItemName(itemId); searchString += functionName; var goInstanceId = frameData.GetItemInstanceID(itemId); if (goInstanceId > 0) { var go = EditorUtility.InstanceIDToObject(goInstanceId); var typeName = go.GetType().Name; searchString += $" - {go.name} ({typeName})"; } var isMatch = predicate(searchString); if (isMatch) { return(itemId); } else { var itemChildrenIds = new List <int>(); frameData.GetItemChildren(itemId, itemChildrenIds); foreach (var childId in itemChildrenIds) { var foundId = GetItemIdMatchingRecursive(frameData, childId, predicate); if (foundId != -1) { return(foundId); } } } return(-1); }
internal float UpdateData(HierarchyFrameDataView frameDataView, int selectedMarkerId) { totalSelectedPropertyTime = 0; m_Callers.Clear(); m_Callees.Clear(); m_ChildrenIds.Clear(); m_Stack.Clear(); m_Stack.Push(frameDataView.GetRootItemID()); while (m_Stack.Count > 0) { var current = m_Stack.Pop(); if (!frameDataView.HasItemChildren(current)) { continue; } var markerId = frameDataView.GetItemMarkerID(current); frameDataView.GetItemChildren(current, m_ChildrenIds); foreach (var childId in m_ChildrenIds) { var childMarkerId = frameDataView.GetItemMarkerID(childId); if (childMarkerId == selectedMarkerId) { var totalSelfTime = frameDataView.GetItemColumnDataAsSingle(childId, HierarchyFrameDataView.columnTotalTime); totalSelectedPropertyTime += totalSelfTime; if (current != 0) { // Add markerId to callers (except root) CallInformation callInfo; var totalTime = frameDataView.GetItemColumnDataAsSingle(current, HierarchyFrameDataView.columnTotalTime); var calls = (int)frameDataView.GetItemColumnDataAsSingle(current, HierarchyFrameDataView.columnCalls); var gcAlloc = (int)frameDataView.GetItemColumnDataAsSingle(current, HierarchyFrameDataView.columnGcMemory); if (!m_Callers.TryGetValue(markerId, out callInfo)) { m_Callers.Add(markerId, new CallInformation() { id = current, name = frameDataView.GetItemName(current), callsCount = calls, gcAllocBytes = gcAlloc, totalCallTimeMs = totalTime, totalSelfTimeMs = totalSelfTime }); } else { callInfo.callsCount += calls; callInfo.gcAllocBytes += gcAlloc; callInfo.totalCallTimeMs += totalTime; callInfo.totalSelfTimeMs += totalSelfTime; } } } if (markerId == selectedMarkerId) { // Add childMarkerId to callees CallInformation callInfo; var totalTime = frameDataView.GetItemColumnDataAsSingle(childId, HierarchyFrameDataView.columnTotalTime); var calls = (int)frameDataView.GetItemColumnDataAsSingle(childId, HierarchyFrameDataView.columnCalls); var gcAlloc = (int)frameDataView.GetItemColumnDataAsSingle(childId, HierarchyFrameDataView.columnGcMemory); if (!m_Callees.TryGetValue(childMarkerId, out callInfo)) { m_Callees.Add(childMarkerId, new CallInformation() { id = childId, name = frameDataView.GetItemName(childId), callsCount = calls, gcAllocBytes = gcAlloc, totalCallTimeMs = totalTime, totalSelfTimeMs = 0 }); } else { callInfo.callsCount += calls; callInfo.gcAllocBytes += gcAlloc; callInfo.totalCallTimeMs += totalTime; } } m_Stack.Push(childId); } } UpdateCallsData(ref m_CallersData, m_Callers, totalSelectedPropertyTime); UpdateCallsData(ref m_CalleesData, m_Callees, totalSelectedPropertyTime); return(totalSelectedPropertyTime); }
void MigrateSelectedState(bool expandIfNecessary) { if (m_SelectedItemMarkerIdPath == null && m_LegacySelectedItemMarkerNamePath == null) { return; } // Find view id which corresponds to markerPath var newSelectedId = m_FrameDataView.GetRootItemID(); bool selectedItemsPathIsExpanded = true; if (m_SelectedItemMarkerIdPath != null) { foreach (var marker in m_SelectedItemMarkerIdPath) { if (m_FrameDataView.HasItemChildren(newSelectedId)) { m_FrameDataView.GetItemChildren(newSelectedId, m_ReusableChildrenIds); foreach (var childId in m_ReusableChildrenIds) { if (marker == m_FrameDataView.GetItemMarkerID(childId)) { // check if the parent is expanded if (!IsExpanded(newSelectedId)) { selectedItemsPathIsExpanded = false; } newSelectedId = childId; break; } } } if (newSelectedId == 0) { break; } } } else if (m_LegacySelectedItemMarkerNamePath != null) { var markerIdPath = new List <int>(); var markerNames = m_LegacySelectedItemMarkerNamePath.Split('/'); foreach (var markerName in markerNames) { if (m_FrameDataView.HasItemChildren(newSelectedId)) { m_FrameDataView.GetItemChildren(newSelectedId, m_ReusableChildrenIds); foreach (var childId in m_ReusableChildrenIds) { if (markerName == m_FrameDataView.GetItemName(childId)) { // check if the parent is expanded if (!IsExpanded(newSelectedId)) { selectedItemsPathIsExpanded = false; } newSelectedId = childId; markerIdPath.Add(m_FrameDataView.GetItemMarkerID(childId)); break; } } } if (newSelectedId == 0) { break; } } m_SelectedItemMarkerIdPath = markerIdPath; m_LegacySelectedItemMarkerNamePath = null; } var newSelection = (newSelectedId == 0) ? new List <int>() : new List <int>() { newSelectedId }; state.selectedIDs = newSelection; // Framing invalidates expanded state and this is very expensive operation to perform each frame. // Thus we auto frame selection only when we are not profiling. var collectingSamples = ProfilerDriver.enabled && (ProfilerDriver.profileEditor || EditorApplication.isPlaying); var isFramingAllowed = !collectingSamples; if (newSelectedId != 0 && isInitialized && isFramingAllowed && (selectedItemsPathIsExpanded || expandIfNecessary)) { FrameItem(newSelectedId); } }
internal void UpdateData(HierarchyFrameDataView frameDataView, int selectedMarkerId) { totalSelectedPropertyTime = 0; m_Callers.Clear(); m_Callees.Clear(); m_ChildrenIds.Clear(); m_Stack.Clear(); m_Stack.Push(frameDataView.GetRootItemID()); while (m_Stack.Count > 0) { var current = m_Stack.Pop(); if (!frameDataView.HasItemChildren(current)) { continue; } var markerId = frameDataView.GetItemMarkerID(current); frameDataView.GetItemChildren(current, m_ChildrenIds); foreach (var childId in m_ChildrenIds) { var childMarkerId = frameDataView.GetItemMarkerID(childId); if (childMarkerId == selectedMarkerId) { var totalSelfTime = frameDataView.GetItemColumnDataAsSingle(childId, HierarchyFrameDataView.columnTotalTime); totalSelectedPropertyTime += totalSelfTime; // Skip root sample if (current != 0) { // Add markerId to callers (except root) CallInformation callInfo; var totalTime = frameDataView.GetItemColumnDataAsSingle(current, HierarchyFrameDataView.columnTotalTime); // Display sample details in the scope of caller. var calls = (int)frameDataView.GetItemColumnDataAsSingle(childId, HierarchyFrameDataView.columnCalls); var gcAlloc = (int)frameDataView.GetItemColumnDataAsSingle(childId, HierarchyFrameDataView.columnGcMemory); if (!m_Callers.TryGetValue(markerId, out callInfo)) { m_Callers.Add(markerId, new CallInformation() { id = current, name = profilerSampleNameProvider.GetItemName(frameDataView, current), callsCount = calls, gcAllocBytes = gcAlloc, totalCallTimeMs = totalTime, totalSelfTimeMs = totalSelfTime }); } else { callInfo.callsCount += calls; // Ignore adding time and gc allocations for recursive like calls if (markerId != childMarkerId) { callInfo.gcAllocBytes += gcAlloc; callInfo.totalCallTimeMs += totalTime; callInfo.totalSelfTimeMs += totalSelfTime; } } } } if (markerId == selectedMarkerId) { // Add childMarkerId to callees CallInformation callInfo; var totalTime = frameDataView.GetItemColumnDataAsSingle(childId, HierarchyFrameDataView.columnTotalTime); var calls = (int)frameDataView.GetItemColumnDataAsSingle(childId, HierarchyFrameDataView.columnCalls); var gcAlloc = (int)frameDataView.GetItemColumnDataAsSingle(childId, HierarchyFrameDataView.columnGcMemory); if (!m_Callees.TryGetValue(childMarkerId, out callInfo)) { m_Callees.Add(childMarkerId, new CallInformation() { id = childId, name = profilerSampleNameProvider.GetItemName(frameDataView, childId), callsCount = calls, gcAllocBytes = gcAlloc, totalCallTimeMs = totalTime, totalSelfTimeMs = 0 }); } else { callInfo.callsCount += calls; // Ignore adding time and gc allocations for recursive like calls if (markerId != childMarkerId) { callInfo.gcAllocBytes += gcAlloc; callInfo.totalCallTimeMs += totalTime; } } } m_Stack.Push(childId); } } UpdateCallsData(ref m_CallersData, m_Callers, totalSelectedPropertyTime); UpdateCallsData(ref m_CalleesData, m_Callees, totalSelectedPropertyTime); }
void Search(TreeViewItem searchFromThis, string search, List <TreeViewItem> result) { if (searchFromThis == null) { throw new ArgumentException("Invalid searchFromThis: cannot be null", "searchFromThis"); } if (string.IsNullOrEmpty(search)) { throw new ArgumentException("Invalid search: cannot be null or empty", "search"); } const int kItemDepth = 0; // tree is flattened when searching var stack = new Stack <int>(); m_FrameDataView.GetItemChildren(searchFromThis.id, m_ReusableChildrenIds); foreach (var childId in m_ReusableChildrenIds) { stack.Push(childId); } while (stack.Count > 0) { var current = stack.Pop(); // Matches search? var functionName = m_ProfilerSampleNameProvider.GetItemName(m_FrameDataView, current); if (functionName.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0) { var item = AcquireFrameDataTreeViewItem(m_FrameDataView, current, kItemDepth, searchFromThis); item.displayName = functionName; item.sortWeight = m_FrameDataView.GetItemColumnDataAsFloat(current, m_FrameDataView.sortColumn); searchFromThis.AddChild(item); result.Add(item); } m_FrameDataView.GetItemChildren(current, m_ReusableChildrenIds); foreach (var childId in m_ReusableChildrenIds) { stack.Push(childId); } } // Sort filtered results based on HerarchyFrameData sorting settings var sortModifier = m_FrameDataView.sortColumnAscending ? 1 : -1; result.Sort((_x, _y) => { var x = _x as FrameDataTreeViewItem; var y = _y as FrameDataTreeViewItem; if ((x == null) || (y == null)) { return(0); } int retVal; if (x.sortWeight != y.sortWeight) { retVal = x.sortWeight < y.sortWeight ? -1 : 1; } else { retVal = EditorUtility.NaturalCompare(x.displayName, y.displayName); } return(retVal * sortModifier); }); }