Beispiel #1
0
        public int UpdateSize(string label, int x, int y, int padding, int height, int width = -1)
        {
            _visible = true;
            _label   = label;

            if (width == -1)
            {
                // Dummy draw to measure size
                width = (int)_fontService.DrawText(label, 0, 0, height, false);
            }

            UpdateSize(x, y, padding, width, height);

            return(_right - _left);
        }
Beispiel #2
0
        /// <summary>
        /// Profile Render Loop
        /// </summary>
        /// <remarks>There is no need to call the base implementation.</remarks>
        public void Draw()
        {
            if (!_visible || !_initComplete)
            {
                return;
            }

            // Update viewport
            if (_viewportUpdated)
            {
                GL.Viewport(0, 0, Width, Height);

                GL.MatrixMode(MatrixMode.Projection);
                GL.LoadIdentity();
                GL.Ortho(0, Width, 0, Height, 0.0, 4.0);

                _fontService.UpdateScreenHeight(Height);

                _viewportUpdated = false;
                _redrawPending   = true;
            }

            if (!_redrawPending)
            {
                return;
            }

            // Frame setup
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            GL.ClearColor(Color.Black);

            _fontService.fontColor = Color.White;
            int verticalIndex = 0;

            float width;
            float maxWidth = 0;
            float yOffset  = _scrollPos - TitleHeight;
            float xOffset  = 10;
            float timingDataLeft;
            float timingWidth;

            // Background lines to make reading easier
            #region Background Lines
            GL.Enable(EnableCap.ScissorTest);
            GL.Scissor(0, BottomBarHeight, Width, Height - TitleHeight - BottomBarHeight);
            GL.Begin(PrimitiveType.Triangles);
            GL.Color3(0.2f, 0.2f, 0.2f);
            for (int i = 0; i < _sortedProfileData.Count; i += 2)
            {
                float top    = GetLineY(yOffset, LineHeight, LinePadding, false, i - 1);
                float bottom = GetLineY(yOffset, LineHeight, LinePadding, false, i);

                // Skip rendering out of bounds bars
                if (top < 0 || bottom > Height)
                {
                    continue;
                }

                GL.Vertex2(0, bottom);
                GL.Vertex2(0, top);
                GL.Vertex2(Width, top);

                GL.Vertex2(Width, top);
                GL.Vertex2(Width, bottom);
                GL.Vertex2(0, bottom);
            }
            GL.End();
            _maxScroll = (LineHeight + LinePadding) * (_sortedProfileData.Count - 1);
            #endregion

            lock (_profileDataLock)
            {
// Display category
                #region Category
                verticalIndex = 0;
                foreach (var entry in _sortedProfileData)
                {
                    if (entry.Key.Category == null)
                    {
                        verticalIndex++;
                        continue;
                    }

                    float y = GetLineY(yOffset, LineHeight, LinePadding, true, verticalIndex++);
                    width = _fontService.DrawText(entry.Key.Category, xOffset, y, LineHeight);

                    if (width > maxWidth)
                    {
                        maxWidth = width;
                    }
                }
                GL.Disable(EnableCap.ScissorTest);

                width = _fontService.DrawText("Category", xOffset, Height - TitleFontHeight, TitleFontHeight);
                if (width > maxWidth)
                {
                    maxWidth = width;
                }

                xOffset += maxWidth + ColumnSpacing;
                #endregion

// Display session group
                #region Session Group
                maxWidth      = 0;
                verticalIndex = 0;

                GL.Enable(EnableCap.ScissorTest);
                foreach (var entry in _sortedProfileData)
                {
                    if (entry.Key.SessionGroup == null)
                    {
                        verticalIndex++;
                        continue;
                    }

                    float y = GetLineY(yOffset, LineHeight, LinePadding, true, verticalIndex++);
                    width = _fontService.DrawText(entry.Key.SessionGroup, xOffset, y, LineHeight);

                    if (width > maxWidth)
                    {
                        maxWidth = width;
                    }
                }
                GL.Disable(EnableCap.ScissorTest);

                width = _fontService.DrawText("Group", xOffset, Height - TitleFontHeight, TitleFontHeight);
                if (width > maxWidth)
                {
                    maxWidth = width;
                }

                xOffset += maxWidth + ColumnSpacing;
                #endregion

// Display session item
                #region Session Item
                maxWidth      = 0;
                verticalIndex = 0;
                GL.Enable(EnableCap.ScissorTest);
                foreach (var entry in _sortedProfileData)
                {
                    if (entry.Key.SessionItem == null)
                    {
                        verticalIndex++;
                        continue;
                    }

                    float y = GetLineY(yOffset, LineHeight, LinePadding, true, verticalIndex++);
                    width = _fontService.DrawText(entry.Key.SessionItem, xOffset, y, LineHeight);

                    if (width > maxWidth)
                    {
                        maxWidth = width;
                    }
                }
                GL.Disable(EnableCap.ScissorTest);

                width = _fontService.DrawText("Item", xOffset, Height - TitleFontHeight, TitleFontHeight);
                if (width > maxWidth)
                {
                    maxWidth = width;
                }

                xOffset += maxWidth + ColumnSpacing;
                _buttons[(int)ButtonIndex.TagTitle].UpdateSize(0, Height - TitleFontHeight, 0, (int)xOffset, TitleFontHeight);
                #endregion

                // Timing data
                timingWidth    = Width - xOffset - 370;
                timingDataLeft = xOffset;

                GL.Scissor((int)xOffset, BottomBarHeight, (int)timingWidth, Height - TitleHeight - BottomBarHeight);

                if (_displayGraph)
                {
                    DrawGraph(xOffset, yOffset, timingWidth);
                }
                else
                {
                    DrawBars(xOffset, yOffset, timingWidth);
                }

                GL.Scissor(0, BottomBarHeight, Width, Height - TitleHeight - BottomBarHeight);

                if (!_displayGraph)
                {
                    _fontService.DrawText("Blue: Instant,  Green: Avg,  Red: Total", xOffset, Height - TitleFontHeight, TitleFontHeight);
                }

                xOffset = Width - 360;

// Display timestamps
                #region Timestamps
                verticalIndex = 0;
                long totalInstant = 0;
                long totalAverage = 0;
                long totalTime    = 0;
                long totalCount   = 0;

                GL.Enable(EnableCap.ScissorTest);
                foreach (var entry in _sortedProfileData)
                {
                    float y = GetLineY(yOffset, LineHeight, LinePadding, true, verticalIndex++);

                    _fontService.DrawText($"{GetTimeString(entry.Value.Instant)} ({entry.Value.InstantCount})", xOffset, y, LineHeight);

                    _fontService.DrawText(GetTimeString(entry.Value.AverageTime), 150 + xOffset, y, LineHeight);

                    _fontService.DrawText(GetTimeString(entry.Value.TotalTime), 260 + xOffset, y, LineHeight);

                    totalInstant += entry.Value.Instant;
                    totalAverage += entry.Value.AverageTime;
                    totalTime    += entry.Value.TotalTime;
                    totalCount   += entry.Value.InstantCount;
                }
                GL.Disable(EnableCap.ScissorTest);

                float yHeight = Height - TitleFontHeight;

                _fontService.DrawText("Instant (Count)", xOffset, yHeight, TitleFontHeight);
                _buttons[(int)ButtonIndex.InstantTitle].UpdateSize((int)xOffset, (int)yHeight, 0, 130, TitleFontHeight);

                _fontService.DrawText("Average", 150 + xOffset, yHeight, TitleFontHeight);
                _buttons[(int)ButtonIndex.AverageTitle].UpdateSize((int)(150 + xOffset), (int)yHeight, 0, 130, TitleFontHeight);

                _fontService.DrawText("Total (ms)", 260 + xOffset, yHeight, TitleFontHeight);
                _buttons[(int)ButtonIndex.TotalTitle].UpdateSize((int)(260 + xOffset), (int)yHeight, 0, Width, TitleFontHeight);

                // Totals
                yHeight = FilterHeight + 3;
                int textHeight = LineHeight - 2;

                _fontService.fontColor = new Color(100, 100, 255, 255);
                float tempWidth = _fontService.DrawText($"Host {GetTimeString(_timingFlagsLast[(int)TimingFlagType.SystemFrame])} " +
                                                        $"({GetTimeString(_timingFlagsAverages[(int)TimingFlagType.SystemFrame])})", 5, yHeight, textHeight);

                _fontService.fontColor = Color.Red;
                _fontService.DrawText($"Game {GetTimeString(_timingFlagsLast[(int)TimingFlagType.FrameSwap])} " +
                                      $"({GetTimeString(_timingFlagsAverages[(int)TimingFlagType.FrameSwap])})", 15 + tempWidth, yHeight, textHeight);
                _fontService.fontColor = Color.White;


                _fontService.DrawText($"{GetTimeString(totalInstant)} ({totalCount})", xOffset, yHeight, textHeight);
                _fontService.DrawText(GetTimeString(totalAverage), 150 + xOffset, yHeight, textHeight);
                _fontService.DrawText(GetTimeString(totalTime), 260 + xOffset, yHeight, textHeight);
                #endregion
            }

            #region Bottom bar
            // Show/Hide Inactive
            float widthShowHideButton = _buttons[(int)ButtonIndex.ShowHideInactive].UpdateSize($"{(_showInactive ? "Hide" : "Show")} Inactive", 5, 5, 4, 16);

            // Play/Pause
            float widthPlayPauseButton = _buttons[(int)ButtonIndex.Pause].UpdateSize(_paused ? "Play" : "Pause", 15 + (int)widthShowHideButton, 5, 4, 16) + widthShowHideButton;

            // Step
            float widthStepButton = widthPlayPauseButton;

            if (_paused)
            {
                widthStepButton += _buttons[(int)ButtonIndex.Step].UpdateSize("Step", (int)(25 + widthPlayPauseButton), 5, 4, 16) + 10;
                _buttons[(int)ButtonIndex.Step].Draw();
            }

            // Change display
            float widthChangeDisplay = _buttons[(int)ButtonIndex.ChangeDisplay].UpdateSize($"View: {(_displayGraph ? "Graph" : "Bars")}", 25 + (int)widthStepButton, 5, 4, 16) + widthStepButton;

            width = widthChangeDisplay;

            if (_displayGraph)
            {
                width += _buttons[(int)ButtonIndex.ToggleFlags].UpdateSize($"{(_displayFlags ? "Hide" : "Show")} Flags", 35 + (int)widthChangeDisplay, 5, 4, 16) + 10;
                _buttons[(int)ButtonIndex.ToggleFlags].Draw();
            }

            // Filter bar
            _fontService.DrawText($"{(_regexEnabled ? "Regex " : "Filter")}: {_filterText}", 35 + width, 7, 16);
            _buttons[(int)ButtonIndex.FilterBar].UpdateSize((int)(45 + width), 0, 0, Width, FilterHeight);
            #endregion

            // Draw buttons
            for (int i = 0; i < (int)ButtonIndex.Autodraw; i++)
            {
                _buttons[i].Draw();
            }

// Dividing lines
            #region Dividing lines
            GL.Color3(Color.White);
            GL.Begin(PrimitiveType.Lines);
            // Top divider
            GL.Vertex2(0, Height - TitleHeight);
            GL.Vertex2(Width, Height - TitleHeight);

            // Bottom divider
            GL.Vertex2(0, FilterHeight);
            GL.Vertex2(Width, FilterHeight);

            GL.Vertex2(0, BottomBarHeight);
            GL.Vertex2(Width, BottomBarHeight);

            // Bottom vertical dividers
            GL.Vertex2(widthShowHideButton + 10, 0);
            GL.Vertex2(widthShowHideButton + 10, FilterHeight);

            GL.Vertex2(widthPlayPauseButton + 20, 0);
            GL.Vertex2(widthPlayPauseButton + 20, FilterHeight);

            if (_paused)
            {
                GL.Vertex2(widthStepButton + 20, 0);
                GL.Vertex2(widthStepButton + 20, FilterHeight);
            }

            if (_displayGraph)
            {
                GL.Vertex2(widthChangeDisplay + 30, 0);
                GL.Vertex2(widthChangeDisplay + 30, FilterHeight);
            }

            GL.Vertex2(width + 30, 0);
            GL.Vertex2(width + 30, FilterHeight);

            // Column dividers
            float timingDataTop = Height - TitleHeight;

            GL.Vertex2(timingDataLeft, FilterHeight);
            GL.Vertex2(timingDataLeft, timingDataTop);

            GL.Vertex2(timingWidth + timingDataLeft, FilterHeight);
            GL.Vertex2(timingWidth + timingDataLeft, timingDataTop);
            GL.End();
            #endregion

            _redrawPending = false;
            SwapBuffers();
        }