private void Reflesh(int frameIdx, bool force = false)
        {
            if (lastPreviewFrameIdx == frameIdx && !force)
            {
                return;
            }
            HierarchyFrameDataView hierarchyFrameDataView =
                ProfilerDriver.GetHierarchyFrameDataView(frameIdx, 0, HierarchyFrameDataView.ViewModes.Default, 0, false);;
            NativeArray <byte> bytes =
                hierarchyFrameDataView.GetFrameMetaData <byte>(ScreenShotToProfiler.MetadataGuid, ScreenShotToProfiler.InfoTag);

            if (bytes != null && bytes.Length >= 12)
            {
                var tagInfo = GenerateTagInfo(bytes);
                SetOutputSize(tagInfo);
                if (originTexture)
                {
                    Object.DestroyImmediate(originTexture);
                }
                originTexture = GenerateTagTexture(tagInfo, frameIdx);
                //this.drawTextureInfo.SetupToRenderTexture(originTexture);
            }
            else
            {
                //this.drawTextureInfo.SetupToRenderTexture(null);

                if (originTexture)
                {
                    Object.DestroyImmediate(originTexture);
                }
                originTexture = null;
            }
            lastPreviewFrameIdx = frameIdx;
        }
        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 DrawToolbar(HierarchyFrameDataView frameDataView, bool showDetailedView, ref bool updateViewLive, ProfilerViewType viewType)
        {
            EditorGUILayout.BeginHorizontal(BaseStyles.toolbar);

            DrawViewTypePopup(viewType);

            DrawLiveUpdateToggle(ref updateViewLive);
            if (!gpuView)
            {
                DrawThreadPopup(frameDataView);
            }


            GUILayout.FlexibleSpace();

            if (frameDataView != null && frameDataView.valid)
            {
                DrawCPUGPUTime(frameDataView.frameTimeMs, frameDataView.frameGpuTimeMs);
            }

            GUILayout.FlexibleSpace();

            DrawSearchBar();

            if (!showDetailedView)
            {
                DrawDetailedViewPopup();
                EditorGUILayout.Space(); // workaround: Remove double lines
                cpuModule?.DrawOptionsMenuPopup();
            }

            EditorGUILayout.EndHorizontal();
        }
예제 #4
0
        private Texture2D GenerateTagTexture(TagInfo info, int idx)
        {
            Texture2D texture = null;

            for (int i = idx; i < idx + 10; ++i)
            {
                HierarchyFrameDataView hierarchyFrameDataView =
                    ProfilerDriver.GetHierarchyFrameDataView(i, 0, HierarchyFrameDataView.ViewModes.Default, 0, false);
                if (hierarchyFrameDataView == null)
                {
                    continue;
                }
                NativeArray <byte> bytes =
                    hierarchyFrameDataView.GetFrameMetaData <byte>(ScreenShotToProfiler.MetadataGuid, info.id);

                if (bytes.IsCreated && bytes.Length > 16)
                {
                    texture = new Texture2D(info.width, info.height, TextureFormat.RGBA32, false);
                    texture.LoadRawTextureData(bytes);
                    texture.Apply();
                    break;
                }
            }
            return(texture);
        }
        private void DrawThreadPopup(HierarchyFrameDataView frameDataView)
        {
            if (!(frameDataView != null && frameDataView.valid))
            {
                var disabledValues = new string[] { m_ThreadName };
                EditorGUILayout.AdvancedPopup(0, disabledValues, BaseStyles.threadSelectionToolbarDropDown, GUILayout.MinWidth(BaseStyles.detailedViewTypeToolbarDropDown.fixedWidth));
                return;
            }

            var newThreadIndex = 0;

            if (threadIndex == 0)
            {
                newThreadIndex = EditorGUILayout.AdvancedLazyPopup(m_ThreadName, threadIndex,
                                                                   (() => GetThreadNamesLazy(frameDataView)),
                                                                   BaseStyles.threadSelectionToolbarDropDown, GUILayout.MinWidth(BaseStyles.detailedViewTypeToolbarDropDown.fixedWidth));
            }
            else
            {
                float minWidth, maxWidth;
                var   content = new GUIContent(m_ThreadName);
                BaseStyles.threadSelectionToolbarDropDown.CalcMinMaxWidth(content, out minWidth, out maxWidth);
                UpdateThreadNamesAndThreadIndex(frameDataView);
                newThreadIndex = EditorGUILayout.AdvancedPopup(threadIndex, m_ThreadNames, BaseStyles.threadSelectionToolbarDropDown, GUILayout.MinWidth(Math.Max(BaseStyles.detailedViewTypeToolbarDropDown.fixedWidth, minWidth)));
            }

            if (newThreadIndex != threadIndex)
            {
                threadIndex  = newThreadIndex;
                m_ThreadName = m_ThreadNames[threadIndex];
                cpuModule.Repaint();
                EditorGUIUtility.ExitGUI();
            }
        }
        void DrawToolbar(HierarchyFrameDataView frameDataView, bool showDetailedView)
        {
            EditorGUILayout.BeginHorizontal(BaseStyles.toolbar);

            if (frameDataView != null)
            {
                DrawViewTypePopup((frameDataView.viewMode & HierarchyFrameDataView.ViewModes.MergeSamplesWithTheSameName) != 0 ? ProfilerViewType.Hierarchy : ProfilerViewType.RawHierarchy);
            }

            using (new EditorGUI.DisabledScope(!frameDataView.valid))
            {
                DrawThreadPopup(frameDataView);
            }

            GUILayout.FlexibleSpace();

            if (frameDataView != null)
            {
                DrawCPUGPUTime(frameDataView.frameTimeMs, frameDataView.frameGpuTimeMs);
            }

            GUILayout.FlexibleSpace();

            DrawSearchBar();

            if (!showDetailedView)
            {
                DrawDetailedViewPopup();
                DrawOptionsMenuPopup();
            }

            EditorGUILayout.EndHorizontal();
        }
        public void SetFrameDataView(HierarchyFrameDataView frameDataView)
        {
            var needReload  = !Equals(m_FrameDataView, frameDataView);
            var needSorting = frameDataView != null && frameDataView.valid &&
                              (frameDataView.sortColumn != m_MultiColumnHeader.sortedProfilerColumn ||
                               frameDataView.sortColumnAscending != m_MultiColumnHeader.sortedProfilerColumnAscending);

            if (needReload)
            {
                StoreExpandedState();
                StoreSelectedState();
            }

            m_FrameDataView = frameDataView;
            if (needSorting)
            {
                m_FrameDataView.Sort(m_MultiColumnHeader.sortedProfilerColumn, m_MultiColumnHeader.sortedProfilerColumnAscending);
            }

            if (needReload || needSorting)
            {
                m_ShouldExecuteDelayedSearch = true;
                Reload();
            }
        }
        public void DoGUI(GUIStyle headerStyle, HierarchyFrameDataView frameDataView, IList <int> selection)
        {
            if (frameDataView == null || !frameDataView.valid || selection.Count == 0)
            {
                DrawEmptyPane(headerStyle);
                return;
            }

            var selectedId = selection[0];

            InitIfNeeded();
            UpdateIfNeeded(frameDataView, selectedId);

            GUILayout.Label(m_TotalSelectedPropertyTimeLabel, EditorStyles.label);
            SplitterGUILayout.BeginVerticalSplit(m_VertSplit, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));

            // Callees
            var rect = EditorGUILayout.BeginHorizontal();

            m_CalleesTreeView.OnGUI(rect);
            EditorGUILayout.EndHorizontal();

            // Callers
            rect = EditorGUILayout.BeginHorizontal();
            m_CallersTreeView.OnGUI(rect);
            EditorGUILayout.EndHorizontal();

            SplitterGUILayout.EndVerticalSplit();
        }
        public string GetItemName(HierarchyFrameDataView frameData, int itemId)
        {
            var name = frameData.GetItemName(itemId);

            if ((ViewOptions & ProfilerViewFilteringOptions.ShowFullScriptingMethodNames) != 0)
            {
                return(name);
            }

            var flags = frameData.GetItemMarkerFlags(itemId);

            if (((int)flags & k_AnyFullManagedMarker) == 0)
            {
                return(name);
            }

            var namespaceDelimiterIndex = name.IndexOf(':');

            if (namespaceDelimiterIndex == -1)
            {
                return(name);
            }
            ++namespaceDelimiterIndex;
            if (namespaceDelimiterIndex < name.Length && name[namespaceDelimiterIndex] == ':')
            {
                return(name.Substring(namespaceDelimiterIndex + 1));
            }

            return(name);
        }
예제 #10
0
        static ProfilerColors()
        {
            // Areas are defined by stats in ProfilerStats.cpp file.
            // Color are driven by CPU profiler chart area colors and must be consistent with CPU timeline sample colors.
            // Sample color is defined by ProfilerGroup (category) and defined in s_ProfilerGroupInfos table.
            s_DefaultColors = new Color[]
            {
                HierarchyFrameDataView.GetMarkerCategoryColor(0),                   // "Rendering"
                HierarchyFrameDataView.GetMarkerCategoryColor(1),                   // "Scripts"
                HierarchyFrameDataView.GetMarkerCategoryColor(5),                   // "Physics"
                HierarchyFrameDataView.GetMarkerCategoryColor(6),                   // "Animation"
                HierarchyFrameDataView.GetMarkerCategoryColor(17),                  // "GarbageCollector"
                HierarchyFrameDataView.GetMarkerCategoryColor(18),                  // "VSync"
                HierarchyFrameDataView.GetMarkerCategoryColor(13),                  // "Global Illumination"
                HierarchyFrameDataView.GetMarkerCategoryColor(26),                  // "UI"
                new Color(122.0f / 255.0f, 123.0f / 255.0f, 30.0f / 255.0f, 1.0f),  // "Others"

                new Color(240.0f / 255.0f, 128.0f / 255.0f, 128.0f / 255.0f, 1.0f), // light-coral
                new Color(169.0f / 255.0f, 169.0f / 255.0f, 169.0f / 255.0f, 1.0f), // dark-gray
                new Color(139.0f / 255.0f, 0.0f, 139.0f / 255.0f, 1.0f),            // dark-magenta
                new Color(255.0f / 255.0f, 228.0f / 255.0f, 181.0f / 255.0f, 1.0f), // moccasin
                new Color(32.0f / 255.0f, 178.0f / 255.0f, 170.0f / 255.0f, 1.0f),  // light-sea-green
                new Color(0.4831376f, 0.6211768f, 0.0219608f, 1.0f),
                new Color(0.3827448f, 0.2886272f, 0.5239216f, 1.0f),
                new Color(0.8f, 0.4423528f, 0.0f, 1.0f),
                new Color(0.4486272f, 0.4078432f, 0.050196f, 1.0f),
                new Color(0.4831376f, 0.6211768f, 0.0219608f, 1.0f),
            };
            s_ColorBlindSafeColors = new Color[s_DefaultColors.Length];
            VisionUtility.GetColorBlindSafePalette(s_ColorBlindSafeColors, 0.3f, 1f);
        }
예제 #11
0
        private void DrawThreadPopup(HierarchyFrameDataView frameDataView)
        {
            if (!frameDataView.valid)
            {
                var disabledValues = new string[] { m_ThreadName };
                EditorGUILayout.AdvancedPopup(0, disabledValues, BaseStyles.detailedViewTypeToolbarDropDown, GUILayout.Width(BaseStyles.detailedViewTypeToolbarDropDown.fixedWidth));
                return;
            }

            var newThreadIndex = 0;

            if (m_ThreadIndex == 0)
            {
                newThreadIndex = EditorGUILayout.AdvancedLazyPopup(m_ThreadName, m_ThreadIndex,
                                                                   (() => GetThreadNamesLazy(frameDataView)),
                                                                   BaseStyles.detailedViewTypeToolbarDropDown, GUILayout.Width(BaseStyles.detailedViewTypeToolbarDropDown.fixedWidth));
            }
            else
            {
                UpdateThreadNamesAndThreadIndex(frameDataView);
                newThreadIndex = EditorGUILayout.AdvancedPopup(m_ThreadIndex, m_ThreadNames, BaseStyles.detailedViewTypeToolbarDropDown, GUILayout.Width(BaseStyles.detailedViewTypeToolbarDropDown.fixedWidth));
            }

            if (newThreadIndex != m_ThreadIndex)
            {
                m_ThreadIndex = newThreadIndex;
                m_ThreadName  = m_ThreadNames[m_ThreadIndex];
            }
        }
예제 #12
0
 internal void Init(HierarchyFrameDataView frameDataView, int id, int depth, TreeViewItem parent)
 {
     this.id          = id;
     this.depth       = depth;
     this.parent      = parent;
     this.displayName = null;
     m_FrameDataView  = frameDataView;
     m_Initialized    = false;
 }
        private void DrawThreadPopup(HierarchyFrameDataView frameDataView)
        {
            if (!frameDataView.valid)
            {
                var disabledValues = new string[] { m_ThreadName };
                EditorGUILayout.AdvancedPopup(0, disabledValues, BaseStyles.detailedViewTypeToolbarDropDown, GUILayout.Width(BaseStyles.detailedViewTypeToolbarDropDown.fixedWidth));
                return;
            }

            if (m_FrameIndex != frameDataView.frameIndex)
            {
                m_FrameIndex  = frameDataView.frameIndex;
                m_ThreadIndex = 0;

                using (var frameIterator = new ProfilerFrameDataIterator())
                {
                    var threadCount = frameIterator.GetThreadCount(m_FrameIndex);
                    m_ThreadNames   = new string[threadCount];
                    m_ThreadIndices = new int[threadCount];
                    for (var i = 0; i < threadCount; ++i)
                    {
                        frameIterator.SetRoot(m_FrameIndex, i);
                        var groupName  = frameIterator.GetGroupName();
                        var threadName = frameIterator.GetThreadName();
                        var name       = string.IsNullOrEmpty(groupName) ? threadName : groupName + "." + threadName;
                        m_ThreadNames[i]   = name;
                        m_ThreadIndices[i] = i;
                        if (m_ThreadName == name)
                        {
                            m_ThreadIndex = i;
                        }
                    }

                    Array.Sort(m_ThreadNames, m_ThreadIndices, new ThreadComparer());
                    for (var i = 0; i < threadCount; ++i)
                    {
                        if (m_ThreadName == m_ThreadNames[i])
                        {
                            m_ThreadIndex = i;
                        }
                    }
                }
            }

            var newThreadIndex = EditorGUILayout.AdvancedPopup(m_ThreadIndex, m_ThreadNames, BaseStyles.detailedViewTypeToolbarDropDown, GUILayout.Width(BaseStyles.detailedViewTypeToolbarDropDown.fixedWidth));

            if (newThreadIndex != m_ThreadIndex)
            {
                m_ThreadIndex = newThreadIndex;
                m_ThreadName  = m_ThreadNames[m_ThreadIndex];
            }
        }
예제 #14
0
        void UpdateIfNeeded(HierarchyFrameDataView frameDataView, int selectedId)
        {
            var needReload = m_SelectedID != selectedId || !Equals(m_FrameDataView, frameDataView);

            if (!needReload)
            {
                return;
            }

            m_FrameDataView = frameDataView;
            m_SelectedID    = selectedId;
            m_TreeView.SetSelection(new List <int>());

            var samplesCount = m_FrameDataView.GetItemMergedSamplesCount(selectedId);
            var columnsCount = m_MultiColumnHeader.columns.Length;

            var objectsData  = new List <ObjectInformation>();
            var objectsDatas = new List <string> [columnsCount];

            // Collect all the data
            var instanceIDs = new List <int>(samplesCount);

            m_FrameDataView.GetItemMergedSamplesInstanceID(selectedId, instanceIDs);
            for (var i = 0; i < columnsCount; i++)
            {
                objectsDatas[i] = new List <string>(samplesCount);
                m_FrameDataView.GetItemMergedSamplesColumnData(selectedId, m_MultiColumnHeader.columns[i].profilerColumn, objectsDatas[i]);
            }

            // Store it per sample
            for (var i = 0; i < samplesCount; i++)
            {
                var objData = new ObjectInformation()
                {
                    columnStrings = new string[columnsCount]
                };
                objData.id          = selectedId;
                objData.sampleIndex = i;

                objData.instanceId = (i < instanceIDs.Count) ? instanceIDs[i] : 0;
                for (var j = 0; j < columnsCount; j++)
                {
                    objData.columnStrings[j] = (i < objectsDatas[j].Count) ? objectsDatas[j][i] : string.Empty;
                }

                objectsData.Add(objData);
            }

            m_TreeView.SetData(objectsData);
        }
        void UpdateThreadNamesAndThreadIndex(HierarchyFrameDataView frameDataView)
        {
            if (m_FrameIndex == frameDataView.frameIndex)
            {
                return;
            }

            m_FrameIndex = frameDataView.frameIndex;
            threadIndex  = 0;

            using (var frameIterator = new ProfilerFrameDataIterator())
            {
                var threadCount = frameIterator.GetThreadCount(m_FrameIndex);
                if (m_ThreadInfoCache == null || m_ThreadInfoCache.Capacity < threadCount)
                {
                    m_ThreadInfoCache = new List <ThreadInfo>(threadCount);
                }
                m_ThreadInfoCache.Clear();

                // Fetch all thread names
                for (var i = 0; i < threadCount; ++i)
                {
                    frameIterator.SetRoot(m_FrameIndex, i);
                    var groupName  = frameIterator.GetGroupName();
                    var threadName = frameIterator.GetThreadName();
                    var name       = string.IsNullOrEmpty(groupName) ? threadName : groupName + "." + threadName;
                    m_ThreadInfoCache.Add(new ThreadInfo()
                    {
                        groupOrder = GetGroupOrder(name), fullName = name
                    });
                }

                m_ThreadInfoCache.Sort();

                if (m_ThreadNames == null || m_ThreadNames.Length != threadCount)
                {
                    m_ThreadNames = new string[threadCount];
                }
                // Make a display list with a current index selected
                for (var i = 0; i < threadCount; ++i)
                {
                    m_ThreadNames[i] = m_ThreadInfoCache[i].fullName;
                    if (m_ThreadName == m_ThreadNames[i])
                    {
                        threadIndex = i;
                    }
                }
            }
        }
        public void SetFrameDataView(HierarchyFrameDataView frameDataView)
        {
            InitIfNeeded();

            if (frameDataView.valid)
            {
                threadName     = frameDataView.threadName;
                groupName      = frameDataView.threadGroupName;
                threadId       = frameDataView.threadId;
                threadIndex    = frameDataView.threadIndex;
                fullThreadName = string.IsNullOrEmpty(groupName) ? threadName : $"{groupName}.{threadName}";
            }
            m_TreeView.SetFrameDataView(frameDataView);
            UpdateThreadNamesAndThreadIndex(frameDataView, forceUpdate: true);
        }
        public void DoGUI(GUIStyle headerStyle, HierarchyFrameDataView frameDataView, IList <int> selection)
        {
            if (frameDataView == null || !frameDataView.valid || selection.Count == 0)
            {
                DrawEmptyPane(headerStyle);
                return;
            }

            InitIfNeeded();
            UpdateIfNeeded(frameDataView, selection[0]);

            string callstack        = null;
            var    selectedSampleId = m_TreeView.GetSelectedFrameDataViewId();

            if (selectedSampleId != -1)
            {
                callstack = frameDataView.ResolveItemMergedSampleCallstack(selectedSampleId, m_TreeView.state.selectedIDs[0]);
            }

            var showCallstack = !string.IsNullOrEmpty(callstack);

            if (showCallstack)
            {
                SplitterGUILayout.BeginVerticalSplit(m_VertSplit, Styles.expandedArea);
            }

            // Detailed list
            var rect = EditorGUILayout.BeginVertical(Styles.expandedArea);

            m_TreeView.OnGUI(rect);

            EditorGUILayout.EndVertical();

            if (showCallstack)
            {
                // Callstack area
                EditorGUILayout.BeginVertical(Styles.expandedArea);
                m_CallstackScrollViewPos = EditorGUILayout.BeginScrollView(m_CallstackScrollViewPos, Styles.callstackScroll);

                var text = kCallstackText + '\n' + callstack;
                EditorGUILayout.TextArea(text, Styles.callstackTextArea);

                EditorGUILayout.EndScrollView();
                EditorGUILayout.EndVertical();

                SplitterGUILayout.EndVerticalSplit();
            }
        }
예제 #18
0
        public void Clear()
        {
            if (m_FrameDataView == null)
            {
                return;
            }

            m_FrameDataView.Dispose();
            m_FrameDataView = null;

            m_RowsPool.Clear();
            m_ChildrenPool.Clear();
            m_ReusableVisitList.Clear();
            m_ReusableChildrenIds.Clear();
            m_TreeTraversalStatePool.Clear();

            Reload();
        }
예제 #19
0
        FrameDataTreeViewItem AcquireFrameDataTreeViewItem(HierarchyFrameDataView frameDataView, int id, int depth, TreeViewItem parent)
        {
            if (m_RowsPool.Count > 0)
            {
                FrameDataTreeViewItem child = (FrameDataTreeViewItem)m_RowsPool[m_RowsPool.Count - 1];
                m_RowsPool.RemoveAt(m_RowsPool.Count - 1);
                child.Init(m_FrameDataView, id, depth, parent);
                if (child.children != null)
                {
                    m_ChildrenPool.Push(child.children);
                    child.children = null;
                }

                return(child);
            }

            return(new FrameDataTreeViewItem(m_FrameDataView, id, depth, parent));
        }
        FrameDataTreeViewItem AcquireFrameDataTreeViewItem(HierarchyFrameDataView frameDataView, int id, int depth, TreeViewItem parent)
        {
            if (m_RowsPoolLastItemIndex > -1)
            {
                FrameDataTreeViewItem child = (FrameDataTreeViewItem)m_RowsPool[m_RowsPoolLastItemIndex];
                --m_RowsPoolLastItemIndex;
                child.Init(m_FrameDataView, id, depth, parent);
                var children = child.children;
                if (children != null)
                {
                    m_ChildrenPool.Push(children);
                    child.children = null;
                }

                return(child);
            }

            return(new FrameDataTreeViewItem(m_FrameDataView, id, depth, parent));
        }
        void DrawToolbar(HierarchyFrameDataView frameDataView, bool showDetailedView, ref bool updateViewLive)
        {
            EditorGUILayout.BeginHorizontal(BaseStyles.toolbar);

            if (frameDataView != null && frameDataView.valid)
            {
                DrawViewTypePopup((frameDataView.viewMode & HierarchyFrameDataView.ViewModes.MergeSamplesWithTheSameName) != 0 ? ProfilerViewType.Hierarchy : ProfilerViewType.RawHierarchy);
            }
            else
            {
                DrawViewTypePopup(ProfilerViewType.Hierarchy);
            }

            DrawLiveUpdateToggle(ref updateViewLive);
            if (!gpuView)
            {
                using (new EditorGUI.DisabledScope(!(frameDataView != null && frameDataView.valid)))
                {
                    DrawThreadPopup(frameDataView);
                }
            }


            GUILayout.FlexibleSpace();

            if (frameDataView != null && frameDataView.valid)
            {
                DrawCPUGPUTime(frameDataView.frameTimeMs, frameDataView.frameGpuTimeMs);
            }

            GUILayout.FlexibleSpace();

            DrawSearchBar();

            if (!showDetailedView)
            {
                DrawDetailedViewPopup();
                EditorGUILayout.Space(); // workaround: Remove double lines
                cpuModule?.DrawOptionsMenuPopup();
            }

            EditorGUILayout.EndHorizontal();
        }
        void UpdateIfNeeded(HierarchyFrameDataView frameDataView, int selectedId)
        {
            var needReload = m_SelectedID != selectedId || !Equals(m_FrameDataView, frameDataView);

            if (!needReload)
            {
                return;
            }

            m_FrameDataView = frameDataView;
            m_SelectedID    = selectedId;

            callersAndCalleeData.UpdateData(m_FrameDataView, m_FrameDataView.GetItemMarkerID(m_SelectedID));

            m_CallersTreeView.SetCallsData(callersAndCalleeData.callersData);
            m_CalleesTreeView.SetCallsData(callersAndCalleeData.calleesData);

            m_TotalSelectedPropertyTimeLabel.text = m_FrameDataView.GetItemName(selectedId) + UnityString.Format(" - Total time: {0:f2} ms", callersAndCalleeData.totalSelectedPropertyTime);
        }
        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);
        }
        public void SetFrameDataView(HierarchyFrameDataView frameDataView)
        {
            InitIfNeeded();

            bool forceUpdateThreadNames = true;

            if (frameDataView.valid)
            {
                // Only reset and rebuild threads cache if we change frame. Otherwise preserve the currently selected index and all threads data.
                forceUpdateThreadNames = frameDataView.frameIndex != m_FrameIndex;

                threadName     = frameDataView.threadName;
                groupName      = frameDataView.threadGroupName;
                threadId       = frameDataView.threadId;
                threadIndex    = frameDataView.threadIndex;
                fullThreadName = string.IsNullOrEmpty(groupName) ? threadName : $"{groupName}.{threadName}";
            }
            m_TreeView.SetFrameDataView(frameDataView);
            UpdateThreadNamesAndThreadIndex(frameDataView, forceUpdateThreadNames);
        }
        void UpdateIfNeeded(HierarchyFrameDataView frameDataView, int selectedId)
        {
            var needReload = m_SelectedID != selectedId || !Equals(m_FrameDataView, frameDataView);

            if (!needReload)
            {
                return;
            }

            m_FrameDataView = frameDataView;
            m_SelectedID    = selectedId;

            callersAndCalleeData.UpdateData(m_FrameDataView, m_FrameDataView.GetItemMarkerID(m_SelectedID));

            m_CallersTreeView.SetCallsData(callersAndCalleeData.callersData);
            m_CalleesTreeView.SetCallsData(callersAndCalleeData.calleesData);

            var sampleDetails = profilerSampleNameProvider.GetItemName(m_FrameDataView, selectedId) + UnityString.Format(" - Total time: {0:f2} ms", callersAndCalleeData.totalSelectedPropertyTime);

            m_TotalSelectedPropertyTimeLabel.text    = sampleDetails;
            m_TotalSelectedPropertyTimeLabel.tooltip = string.Concat(sampleDetails, "\n\n", Content.totalSelectedPropertyTimeTooltip);
        }
        private void DrawThreadPopup(HierarchyFrameDataView frameDataView)
        {
            var   style = BaseStyles.threadSelectionToolbarDropDown;
            var   buttonContent = GUIContent.Temp(m_FullThreadName);
            float minWidth, maxWidth;

            BaseStyles.threadSelectionToolbarDropDown.CalcMinMaxWidth(buttonContent, out minWidth, out maxWidth);
            var position = GUILayoutUtility.GetRect(buttonContent, style, GUILayout.MinWidth(Math.Max(BaseStyles.detailedViewTypeToolbarDropDown.fixedWidth, minWidth)));

            var disabled = !(frameDataView != null && frameDataView.valid);

            using (new EditorGUI.DisabledScope(disabled))
            {
                if (EditorGUI.DropdownButton(position, buttonContent, FocusType.Keyboard, style))
                {
                    UpdateThreadNamesAndThreadIndex(frameDataView);
                    var dropdown = new ProfilerThreadSelectionDropdown(m_ThreadInfoCache, threadIndexInThreadNames, OnThreadSelectionChanged);
                    dropdown.Show(position);
                    GUIUtility.ExitGUI();
                }
            }
        }
예제 #27
0
        public HierarchyFrameDataView GetFrameDataView(string threadName, HierarchyFrameDataView.ViewModes viewMode, int profilerSortColumn, bool sortAscending)
        {
            var frameIndex  = GetActiveVisibleFrameIndex();
            var threadIndex = 0;

            using (var frameIterator = new ProfilerFrameDataIterator())
            {
                var threadCount = frameIterator.GetThreadCount(frameIndex);
                for (var i = 0; i < threadCount; ++i)
                {
                    frameIterator.SetRoot(frameIndex, i);
                    var grp  = frameIterator.GetGroupName();
                    var thrd = frameIterator.GetThreadName();
                    var name = string.IsNullOrEmpty(grp) ? thrd : grp + "." + thrd;
                    if (threadName == name)
                    {
                        threadIndex = i;
                        break;
                    }
                }
            }

            if (m_FrameDataView != null && m_FrameDataView.valid)
            {
                if (m_FrameDataView.frameIndex == frameIndex && m_FrameDataView.threadIndex == threadIndex && m_FrameDataView.viewMode == viewMode)
                {
                    return(m_FrameDataView);
                }
            }

            if (m_FrameDataView != null)
            {
                m_FrameDataView.Dispose();
            }

            m_FrameDataView = new HierarchyFrameDataView(frameIndex, threadIndex, viewMode, profilerSortColumn, sortAscending);
            return(m_FrameDataView);
        }
예제 #28
0
    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);
    }
예제 #29
0
    private void ShowFoundItemInProfiler(HierarchyFrameDataView frameData, int matchingItemId, int frameIndex)
    {
        var goInstanceId = frameData.GetItemInstanceID(matchingItemId);
        var foundObject  = EditorUtility.InstanceIDToObject(goInstanceId);

        //Selection.activeObject = foundObject;
        EditorGUIUtility.PingObject(foundObject);

        var profilerWindowInterface = new ProfilerWindowInterface();

        profilerWindowInterface.OpenProfilerOrUseExisting();
        profilerWindowInterface.JumpToFrame(frameIndex + 1);

        var markerName = frameData.GetItemName(matchingItemId);

        profilerWindowInterface.SetProfilerWindowMarkerName(markerName, new List <string>()
        {
            LookInThread
        });

        ProfilerDriver.enabled     = false;
        EditorApplication.isPaused = true;
    }
예제 #30
0
        public void DoGUI(GUIStyle headerStyle, HierarchyFrameDataView frameDataView, IList <int> selection)
        {
            if (frameDataView == null || !frameDataView.valid || selection.Count == 0)
            {
                DrawEmptyPane(headerStyle);
                return;
            }

            InitIfNeeded();
            UpdateIfNeeded(frameDataView, selection[0]);

            var selectedSampleId            = m_TreeView.GetSelectedFrameDataViewId();
            var selectedMergedSampleIndex   = m_TreeView.GetSelectedFrameDataViewMergedSampleIndex();
            var selectedSampleMetadataCount = 0;

            if (selectedSampleId != -1)
            {
                frameDataView.GetItemMergedSampleCallstack(selectedSampleId, selectedMergedSampleIndex, m_CachedCallstack);
                selectedSampleMetadataCount = frameDataView.GetItemMergedSamplesMetadataCount(selectedSampleId, selectedMergedSampleIndex);
            }

            var showCallstack = m_CachedCallstack.Count > 0;
            var showMetadata  = selectedSampleMetadataCount != 0;

            SplitterGUILayout.BeginVerticalSplit(m_VertSplit, Styles.expandedArea);

            // Detailed list
            var rect = EditorGUILayout.BeginVertical(Styles.expandedArea);

            m_TreeView.OnGUI(rect);

            EditorGUILayout.EndVertical();

            // Callstack area
            EditorGUILayout.BeginVertical(Styles.expandedArea);

            // Display active text (We want word wrapped text with a vertical scrollbar)
            m_CallstackScrollViewPos = EditorGUILayout.BeginScrollView(m_CallstackScrollViewPos, Styles.callstackScroll);

            var sb = new StringBuilder();

            if (showMetadata || showCallstack)
            {
                if (showMetadata)
                {
                    var metadataInfo = frameDataView.GetMarkerMetadataInfo(frameDataView.GetItemMarkerID(selectedSampleId));

                    sb.Append(kMetadataText);
                    sb.Append('\n');
                    for (var i = 0; i < selectedSampleMetadataCount; ++i)
                    {
                        if (metadataInfo != null && i < metadataInfo.Length)
                        {
                            sb.Append(metadataInfo[i].name);
                        }
                        else
                        {
                            sb.Append(i);
                        }
                        sb.Append(": ");
                        sb.Append(frameDataView.GetItemMergedSamplesMetadata(selectedSampleId, selectedMergedSampleIndex, i));
                        sb.Append('\n');
                    }
                    sb.Append('\n');
                }

                if (showCallstack)
                {
                    sb.Append(kCallstackText);
                    sb.Append('\n');
                    foreach (var addr in m_CachedCallstack)
                    {
                        var methodInfo = frameDataView.ResolveMethodInfo(addr);
                        if (string.IsNullOrEmpty(methodInfo.methodName))
                        {
                            sb.AppendFormat("0x{0:X}\n", addr);
                        }
                        else if (string.IsNullOrEmpty(methodInfo.sourceFileName))
                        {
                            sb.AppendFormat("0x{0:X}\t\t{1}\n", addr, methodInfo.methodName);
                        }
                        else
                        {
                            var normalizedPath = methodInfo.sourceFileName.Replace('\\', '/');
                            if (methodInfo.sourceFileLine == 0)
                            {
                                sb.AppendFormat("0x{0:X}\t\t{1}\t<a href=\"{2}\" line=\"1\">{2}</a>\n", addr, methodInfo.methodName, normalizedPath);
                            }
                            else
                            {
                                sb.AppendFormat("0x{0:X}\t\t{1}\t<a href=\"{2}\" line=\"{3}\">{2}:{3}</a>\n", addr, methodInfo.methodName, normalizedPath, methodInfo.sourceFileLine);
                            }
                        }
                    }
                }
            }
            else
            {
                sb.Append(kNoMetadataOrCallstackText);
            }

            var metadataText = sb.ToString();

            Styles.callstackTextArea.CalcMinMaxWidth(GUIContent.Temp(metadataText), out _, out var maxWidth);
            float minHeight = Styles.callstackTextArea.CalcHeight(GUIContent.Temp(metadataText), maxWidth);

            EditorGUILayout.SelectableLabel(metadataText, Styles.callstackTextArea, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true), GUILayout.MinWidth(maxWidth + 10), GUILayout.MinHeight(minHeight + 10));

            EditorGUILayout.EndScrollView();
            EditorGUILayout.EndVertical();

            SplitterGUILayout.EndVerticalSplit();
        }