public int GetItemIDFromRawFrameDataViewIndex(HierarchyFrameDataView frameDataView, int rawSampleIndex, ReadOnlyCollection <int> markerIdPath) { using (var rawFrameDataView = new RawFrameDataView(frameDataView.frameIndex, frameDataView.threadIndex)) { var unreachableDepth = markerIdPath == null ? frameDataView.maxDepth + 1 : markerIdPath.Count; m_CachedDeepestRawSampleIndexPath.Clear(); if (m_CachedDeepestRawSampleIndexPath.Capacity < unreachableDepth) { m_CachedDeepestRawSampleIndexPath.Capacity = unreachableDepth; } string name = null; var foundRawIndex = ProfilerTimelineGUI.FindNextSampleThroughMarkerPath(rawFrameDataView, m_ProfilerSampleNameProvider, markerIdPath, unreachableDepth, ref name, ref m_CachedDeepestRawSampleIndexPath, specificRawSampleIndexToFind: rawSampleIndex); if (foundRawIndex < 0 || foundRawIndex != rawSampleIndex) { return(HierarchyFrameDataView.invalidSampleId); } // We don't care about the path being extended here so, reduce checks by assuming the path is not expanded (this saves calls to IsExpanded) var selectedItemsPathIsExpanded = false; var newSelectedId = GetItemIdFromRawFrameDataIndexPath(frameDataView, m_CachedDeepestRawSampleIndexPath, out int deepestPath, out selectedItemsPathIsExpanded); if (deepestPath < m_CachedDeepestRawSampleIndexPath.Count) { // the path has been cut short and the sample wasn't found return(HierarchyFrameDataView.invalidSampleId); } return(newSelectedId); } }
void MigrateSelectedState(bool expandIfNecessary, bool framingAllowed) { if (m_LocalSelectedItemMarkerIdPath == null || m_Selected == null || m_LocalSelectedItemMarkerIdPath.Count != m_Selected.markerNamePath.Count) { return; } m_SelectionNeedsMigration = false; var markerNamePath = m_Selected.markerNamePath; expandIfNecessary |= m_ExpandDuringNextSelectionMigration; using (k_MigrateSelectionStateMarker.Auto()) { var safeFrameWithSafeMarkerIds = m_Selected.frameIndexIsSafe && m_FrameDataView.frameIndex == m_Selected.safeFrameIndex; var rawHierarchyView = (m_FrameDataView.viewMode & HierarchyFrameDataView.ViewModes.MergeSamplesWithTheSameName) == HierarchyFrameDataView.ViewModes.Default; var allowProxySelection = !safeFrameWithSafeMarkerIds; var finalRawSampleIndex = RawFrameDataView.invalidSampleIndex; using (var frameData = new RawFrameDataView(m_FrameDataView.frameIndex, m_FrameDataView.threadIndex)) { if (!frameData.valid) { return; } if (!safeFrameWithSafeMarkerIds) { // marker names might have changed Ids between frames, update them if that is the case for (int i = 0; i < m_LocalSelectedItemMarkerIdPath.Count; i++) { m_LocalSelectedItemMarkerIdPath[i] = frameData.GetMarkerId(markerNamePath[i]); } } else if (!allowProxySelection) { for (int i = 0; i < m_LocalSelectedItemMarkerIdPath.Count; i++) { var markerIsEditorOnlyMarker = frameData.GetMarkerFlags(m_LocalSelectedItemMarkerIdPath[i]).HasFlag(Unity.Profiling.LowLevel.MarkerFlags.AvailabilityEditor); if (markerIsEditorOnlyMarker && i < m_LocalSelectedItemMarkerIdPath.Count - 1) { // Technically, proxy selections are not supposed to be allowed when switching between views in the same frame. // However, if there are Editor Only markers in the path that are NOT the last item, Hierarchy View might have collapsed the path from this point forward, // so we need to allow Proxy Selections here. allowProxySelection = true; break; } } } var name = m_Selected.sampleDisplayName; m_CachedDeepestRawSampleIndexPath.Clear(); if (m_CachedDeepestRawSampleIndexPath.Capacity < markerNamePath.Count) { m_CachedDeepestRawSampleIndexPath.Capacity = markerNamePath.Count; } if (allowProxySelection || rawHierarchyView) { finalRawSampleIndex = ProfilerTimelineGUI.FindFirstSampleThroughMarkerPath( frameData, m_ProfilerSampleNameProvider, m_LocalSelectedItemMarkerIdPath, markerNamePath.Count, ref name, longestMatchingPath: m_CachedDeepestRawSampleIndexPath); } else { finalRawSampleIndex = ProfilerTimelineGUI.FindNextSampleThroughMarkerPath( frameData, m_ProfilerSampleNameProvider, m_LocalSelectedItemMarkerIdPath, markerNamePath.Count, ref name, ref m_CachedDeepestRawSampleIndexPath); } } var newSelectedId = m_FrameDataView.GetRootItemID(); bool selectedItemsPathIsExpanded = true; var proxySelection = new ProxySelection(); proxySelectionInfo = default; var deepestPath = m_CachedDeepestRawSampleIndexPath.Count; if (finalRawSampleIndex >= 0 || allowProxySelection && deepestPath > 0) { // if a valid raw index was found, find the corresponding HierarchyView Sample id next: newSelectedId = GetItemIdFromRawFrameDataIndexPath(m_FrameDataView, m_CachedDeepestRawSampleIndexPath, out deepestPath, out selectedItemsPathIsExpanded); if (m_LocalSelectedItemMarkerIdPath.Count > deepestPath && newSelectedId >= 0) { proxySelection.hasProxySelection = true; proxySelection.nonProxyName = m_Selected.sampleDisplayName; proxySelection.nonProxySampleStack = m_Selected.markerNamePath; proxySelection.pathLengthDifferenceForProxy = deepestPath - m_LocalSelectedItemMarkerIdPath.Count; } } 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 currently receiving profiler data from the Editor we are profiling, or the user opted into a "Live" view of the data if (newSelectedId != 0 && isInitialized && framingAllowed && (selectedItemsPathIsExpanded || expandIfNecessary)) { FrameItem(newSelectedId); } m_ExpandDuringNextSelectionMigration = false; proxySelectionInfo = proxySelection; } }