Esempio n. 1
0
            // Counts the number of frames that hit each frame time bucket, and works out
            // the percentages that hit 90,75,60, and worse fps.
            public void AnalyseData(ProfileDataset.SampledFunction root)
            {
                m_FrametimeHistogram = new int[m_NumBuckets];
                float[] limits =
                    Enumerable.Range(0, m_NumBuckets).Select(x => 10f + x * m_BucketSize).ToArray();
                limits[m_NumBuckets - 1] = float.MaxValue;
                foreach (var frame in root.frameData.Values)
                {
                    for (int i = 0; i < m_NumBuckets; ++i)
                    {
                        if (frame.totalMilliseconds <= limits[i])
                        {
                            m_FrametimeHistogram[i]++;
                            break;
                        }
                    }
                }
                m_HistogramMax = m_FrametimeHistogram.Max();

                float percentScale = 100.0f / root.frameData.Count;

                m_90fps      = m_FrametimeHistogram.Take(6).Sum() * percentScale;
                m_75fps      = m_FrametimeHistogram.Take(12).Sum() * percentScale;
                m_60fps      = m_FrametimeHistogram.Take(21).Sum() * percentScale;
                m_under60fps = m_FrametimeHistogram.Skip(21).Sum() * percentScale;
            }
Esempio n. 2
0
        /// Sorts the children of a function, depending on the sorting settings.
        private void EnsureSorted(ProfileDataset.SampledFunction fn)
        {
            // If this function is already sorted correctly, early out.
            if (fn.sortIndex == m_sortColumn && fn.sortAscending == m_sortAscending)
            {
                return;
            }

            switch (m_sortColumn)
            {
            case 0:
                fn.sortedChildren = fn.sortedChildren.OrderBy(x => x.id).ToList();
                break;

            case 1:
                fn.sortedChildren = fn.sortedChildren.OrderBy(x => x.name).ToList();
                break;

            case 2:
                fn.sortedChildren = fn.sortedChildren.OrderBy(x => x.frameData.Count).ToList();
                break;

            case 3:
                fn.sortedChildren = fn.sortedChildren.OrderBy(x => x.mean).ToList();
                break;

            case 4:
                fn.sortedChildren = fn.sortedChildren.OrderBy(x => x.median).ToList();
                break;

            case 5:
                fn.sortedChildren = fn.sortedChildren.OrderBy(x => x.min).ToList();
                break;

            case 6:
                fn.sortedChildren = fn.sortedChildren.OrderBy(x => x.max).ToList();
                break;

            case 7:
                fn.sortedChildren = fn.sortedChildren.OrderBy(x => x.medianStdDev).ToList();
                break;

            case 8:
                fn.sortedChildren = fn.sortedChildren.OrderBy(x => x.medianStdDevPc).ToList();
                break;
            }
            if (!m_sortAscending)
            {
                fn.sortedChildren.Reverse();
            }
        }
Esempio n. 3
0
        /// Renders the data in a table.
        /// Sorting is triggered just-in time; each visible list of samples is asked to make sure
        /// they're sorted whenever they are displayed.
        private void RenderData()
        {
            // Draw the header.
            int[]    intWidths = { 50, 400, 100, 100, 100, 100, 100, 120, 120 };
            string[] names     =
            {
                "id",
                "Name",
                "Frame Count",
                "Average ms",
                "Median ms",
                "Min ms",
                "Max ms",
                "Median StdDev",
                "Median StdDev %",
            };
            GUILayoutOption[] widths = intWidths.Select(x => GUILayout.Width(x)).ToArray();
            if (m_Data == null || m_Data.Root == null || m_Data.Root.children == null)
            {
                return;
            }
            GUILayout.BeginVertical();
            Vector2 headerScroll = m_Scroll;

            headerScroll.y = 0;
            GUILayout.BeginScrollView(headerScroll, GUIStyle.none, GUIStyle.none);
            GUILayout.BeginHorizontal();
            for (int i = 0; i < names.Length; ++i)
            {
                // Creates a header titles, with the a marker on the sorting index.
                string marker      = (i == m_sortColumn) ? (m_sortAscending ? " ^" : " v") : "";
                string headerTitle = names[i] + marker;
                // Change sorting parameters.
                if (GUILayout.Button(headerTitle, widths[i]))
                {
                    if (i == m_sortColumn)
                    {
                        m_sortAscending = !m_sortAscending;
                    }
                    else
                    {
                        m_sortColumn = i;
                    }
                }
            }
            GUILayout.EndHorizontal();
            GUILayout.EndScrollView();

            // Draw the rest of the data.
            m_Scroll = GUILayout.BeginScrollView(m_Scroll);

            // Styles for the name section - clipping has to be turned off.
            GUIStyle foldoutStyle = new GUIStyle(EditorStyles.foldout);

            foldoutStyle.clipping = TextClipping.Clip;
            GUIStyle labelStyle = new GUIStyle(foldoutStyle);

            labelStyle.imagePosition     = ImagePosition.TextOnly;
            labelStyle.normal.background = EditorStyles.label.normal.background;

            // Alternate background styles are used for each line to make the table easier to read.
            GUIStyle[] lineStyles = new GUIStyle[2];
            lineStyles[0]        = new GUIStyle(TreeView.DefaultStyles.backgroundEven);
            lineStyles[1]        = new GUIStyle(TreeView.DefaultStyles.backgroundOdd);
            lineStyles[0].border = new RectOffset(3, 3, 3, 3);
            lineStyles[1].border = new RectOffset(3, 3, 3, 3);
            lineStyles[0].margin = new RectOffset(3, 3, 3, 3);
            lineStyles[1].margin = new RectOffset(3, 3, 3, 3);

            // Make sure the children of the root are sorted.
            EnsureSorted(m_Data.Root);

            // Iterate through all children, and their open children - uses a stack instead of recursion.
            var stack = new Stack <IEnumerator <ProfileDataset.SampledFunction> >();

            stack.Push(m_Data.Root.sortedChildren.GetEnumerator());
            // used to work out which color line background to use.
            int lineIndex = 0;

            while (true)
            {
                // Get the next child item, or grab the next enumerator off the stack.
                ProfileDataset.SampledFunction child = null;
                while (true)
                {
                    if (stack.Peek().MoveNext())
                    {
                        child = stack.Peek().Current;
                        break;
                    }
                    stack.Pop();
                    if (!stack.Any())
                    {
                        break;
                    }
                }
                if (child == null)
                {
                    break;
                }

                // Make sure the children are sorted, just-in-time
                EnsureSorted(child);

                GUILayout.BeginHorizontal(lineStyles[lineIndex++ % 2]);
                int columnIndex = 0;
                GUILayout.Label(child.id.ToString(), widths[columnIndex++]);
                int indent = (child.depth - 1) * 10;
                foldoutStyle.fixedWidth = intWidths[columnIndex] - indent;
                labelStyle.fixedWidth   = foldoutStyle.fixedWidth;
                GUILayout.Space(indent);
                if (child.sortedChildren.Any())
                {
                    // A hashset is used to store whether an item with children is expanded.
                    bool wasOpen = m_Expanded.Contains(child.id);
                    bool toggle  = GUILayout.Button(child.name, foldoutStyle);
                    if (toggle)
                    {
                        if (wasOpen)
                        {
                            m_Expanded.Remove(child.id);
                        }
                        else
                        {
                            m_Expanded.Add(child.id);
                        }
                    }
                    if (wasOpen)
                    {
                        stack.Push(child.sortedChildren.GetEnumerator());
                    }
                }
                else
                {
                    GUILayout.Label(child.name, labelStyle);
                }
                columnIndex++;
                GUILayout.Label(child.frameData.Count.ToString(), widths[columnIndex++]);
                GUILayout.Label(child.mean.ToString("F3"), widths[columnIndex++]);
                GUILayout.Label(child.median.ToString("F3"), widths[columnIndex++]);
                GUILayout.Label(child.min.ToString("F3"), widths[columnIndex++]);
                GUILayout.Label(child.max.ToString("F3"), widths[columnIndex++]);
                GUILayout.Label(child.medianStdDev.ToString("F3"), widths[columnIndex++]);
                GUILayout.Label(child.medianStdDevPc.ToString("F0"), widths[columnIndex++]);
                GUILayout.EndHorizontal();
            }
            GUILayout.EndScrollView();

            GUILayout.EndVertical();
        }