Ejemplo n.º 1
0
        private void PropagateSizeGraphPointInner(ulong StreamIndex, int SizeChange)
        {
            if (LastStreamIndex == StreamIndex)
            {
                FSizeGraphPoint LastPoint = SizeGraphPoints[SizeGraphPoints.Count - 1];

                LatestSize += SizeChange;
                if (LatestSize > MaxSize)
                {
                    MaxSize = LatestSize;
                }

                SizeGraphPoints[SizeGraphPoints.Count - 1] = new FSizeGraphPoint(StreamIndex, LastPoint.SizeChange + SizeChange, false);
            }
            else
            {
                LatestSize += SizeChange;
                if (LatestSize > MaxSize)
                {
                    MaxSize = LatestSize;
                }

                SizeGraphPoints.Add(new FSizeGraphPoint(StreamIndex, SizeChange, false));
                LastStreamIndex = StreamIndex;
            }
        }
        private static void RenderSizeGraph(Graphics MyGraphics, List <FSizeGraphPoint> GraphPoints, int GraphWidth, int GraphHeight, float XBase, float XScale, float YScale, bool bXAxisIsFrames, bool bShouldCompleteGraph)
        {
            // Progress bar.
            OwnerWindow.ToolStripProgressBar.Value   = 0;
            OwnerWindow.ToolStripProgressBar.Visible = true;
            long ProgressInterval   = GraphPoints.Count / 20;
            long NextProgressUpdate = ProgressInterval;

            Debug.Assert(GraphPoints != null && GraphPoints.Count > 0);

            //MyGraphics.SmoothingMode = SmoothingMode.AntiAlias;

            FSizeGraphPoint OldPoint    = new FSizeGraphPoint(GraphPoints[0].StreamIndex, 0, false);
            float           OldX        = 0;
            float           OldY        = 0;
            int             NextFrame   = 1;
            int             CurrentSize = 0;

            for (int PointIndex = 0; PointIndex < GraphPoints.Count; PointIndex++)
            {
                // Update progress bar.
                if (PointIndex >= NextProgressUpdate)
                {
                    OwnerWindow.ToolStripProgressBar.PerformStep();
                    NextProgressUpdate += ProgressInterval;
                    Debug.WriteLine("FCallStackHistoryView.RenderSizeGraph " + OwnerWindow.ToolStripProgressBar.Value + "/20");
                }

                FSizeGraphPoint SizeGraphPoint = GraphPoints[PointIndex];

                float X;
                if (bXAxisIsFrames)
                {
                    X = CalculateXForTime(ref NextFrame, SizeGraphPoint.StreamIndex) * XScale - XBase;
                }
                else
                {
                    X = SizeGraphPoint.StreamIndex * XScale - XBase;
                }

                CurrentSize += SizeGraphPoint.SizeChange;

                float Y = CurrentSize * YScale;
                if (X >= 0)
                {
                    if (X < GraphWidth)
                    {
                        MyGraphics.DrawLine(Pens.Black, OldX, GraphHeight - OldY, X, GraphHeight - OldY);
                        MyGraphics.DrawLine(Pens.Black, X, GraphHeight - OldY, X, GraphHeight - Y);
                    }
                    else
                    {
                        break;
                    }
                }

                OldPoint = SizeGraphPoint;
                OldX     = X;
                OldY     = Y;
            }

            // Connect final point to right edge of graph.
            if (bShouldCompleteGraph)
            {
                float FinalLineY = GraphHeight - OldY;
                MyGraphics.DrawLine(Pens.Black, OldX, FinalLineY, GraphWidth, FinalLineY);
            }

            OwnerWindow.ToolStripProgressBar.Visible = false;
        }
        private static void CombineSizeGraphs(List <FCallStack> InCallStacks, List <FSizeGraphPoint> CombinedGraphPoints, BackgroundWorker BGWorker, out long MaximumSize, DoWorkEventArgs EventArgs)
        {
            BGWorker.ReportProgress(0, "Combining size graphs");

            MaximumSize = 0;
            CombinedGraphPoints.Clear();

            int TotalGraphPoints         = 0;
            List <FCallStack> CallStacks = new List <FCallStack>(InCallStacks.Count);
            // Cache this to avoid the hit of calling ToUpperInvariant for every callstack
            string FilterText = OwnerWindow.FilterTextBox.Text.ToUpperInvariant();

            foreach (FCallStack CallStack in InCallStacks)
            {
                // leave out callstacks with empty sizegraphs or not in the selected memory pool
                if (CallStack.SizeGraphPoints.Count > 0 && CallStack.RunFilters(FilterText, OwnerWindow.Options.ClassGroups, OwnerWindow.IsFilteringIn(), OwnerWindow.SelectedMemoryPool))
                {
                    TotalGraphPoints += CallStack.SizeGraphPoints.Count;
                    CallStacks.Add(CallStack);
                }
            }

            List <int> Indices = new List <int>(CallStacks.Count);

            for (int i = 0; i < CallStacks.Count; i++)
            {
                Indices.Add(0);
            }

            int ProgressUpdateCounter = 0;

            long Size = 0;

            while (CallStacks.Count > 0)
            {
                // Check for pending cancellation of a background operation.
                if (BGWorker.CancellationPending)
                {
                    EventArgs.Cancel = true;
                    return;
                }

                ulong MinStreamIndex           = ulong.MaxValue;
                int   BestGraphIndex           = -1;
                bool  bBestPointIsFreshRealloc = false;
                for (int Index = 0; Index < Indices.Count; Index++)
                {
                    FSizeGraphPoint SizeGraphPoint = CallStacks[Index].SizeGraphPoints[Indices[Index]];
                    ulong           StreamIndex    = SizeGraphPoint.StreamIndex;

                    if (StreamIndex < MinStreamIndex)
                    {
                        MinStreamIndex           = StreamIndex;
                        BestGraphIndex           = Index;
                        bBestPointIsFreshRealloc = SizeGraphPoint.bFreshRealloc;
                    }
                    else if (StreamIndex == MinStreamIndex)
                    {
                        if (bBestPointIsFreshRealloc && !SizeGraphPoint.bFreshRealloc)
                        {
                            // this point beats the current best point, because the best point is a fresh realloc
                            // (which causes less accurate memory accounting) and this point isn't
                            bBestPointIsFreshRealloc = SizeGraphPoint.bFreshRealloc;

                            // skip previous best point
                            Indices[BestGraphIndex]++;
                            if (Indices[BestGraphIndex] >= CallStacks[BestGraphIndex].SizeGraphPoints.Count)
                            {
                                // point was last in graph, so remove callstack
                                CallStacks.RemoveAt(BestGraphIndex);
                                Indices.RemoveAt(BestGraphIndex);

                                // bestGraph must be less than i, so we need to adjust i after removing bestGraph
                                Index--;
                            }

                            BestGraphIndex = Index;
                        }
                        else
                        {
                            // This point is worse than or the same as the best point, so skip it to stop it
                            // from coming up in the next iteration (we don't want two graph points for the same
                            // streamindex).
                            Indices[Index]++;
                            if (Indices[Index] >= CallStacks[Index].SizeGraphPoints.Count)
                            {
                                // point was last in graph, so remove callstack and continue processing from next callstack
                                CallStacks.RemoveAt(Index);
                                Indices.RemoveAt(Index);
                                Index--;
                            }
                        }
                    }
                }

                // make sure no two graph points have the same streamindex
                Debug.Assert(CombinedGraphPoints.Count == 0 || CombinedGraphPoints[CombinedGraphPoints.Count - 1].StreamIndex != MinStreamIndex);

                FSizeGraphPoint BestPoint = CallStacks[BestGraphIndex].SizeGraphPoints[Indices[BestGraphIndex]];
                Size += BestPoint.SizeChange;

                CombinedGraphPoints.Add(new FSizeGraphPoint(MinStreamIndex, BestPoint.SizeChange, false));

                Indices[BestGraphIndex]++;
                if (Indices[BestGraphIndex] >= CallStacks[BestGraphIndex].SizeGraphPoints.Count)
                {
                    CallStacks.RemoveAt(BestGraphIndex);
                    Indices.RemoveAt(BestGraphIndex);
                }

                if (Size > MaximumSize)
                {
                    MaximumSize = Size;
                }

                ProgressUpdateCounter++;
                if (BGWorker != null && ProgressUpdateCounter > 10000)
                {
                    BGWorker.ReportProgress(( int )(( float )CombinedGraphPoints.Count / ( float )TotalGraphPoints * 100), "Combining size graphs");
                    ProgressUpdateCounter = 0;
                }
            }
        }
        private static void RenderSizeGraph( Graphics MyGraphics, List<FSizeGraphPoint> GraphPoints, int GraphWidth, int GraphHeight, float XBase, float XScale, float YScale, bool bXAxisIsFrames, bool bShouldCompleteGraph )
        {
            // Progress bar.
            OwnerWindow.ToolStripProgressBar.Value = 0;
            OwnerWindow.ToolStripProgressBar.Visible = true;
            long ProgressInterval = GraphPoints.Count / 20;
            long NextProgressUpdate = ProgressInterval;

            Debug.Assert( GraphPoints != null && GraphPoints.Count > 0 );

            //MyGraphics.SmoothingMode = SmoothingMode.AntiAlias;

            FSizeGraphPoint OldPoint = new FSizeGraphPoint( GraphPoints[ 0 ].StreamIndex, 0, false );
            float OldX = 0;
            float OldY = 0;
            int NextFrame = 1;
            int CurrentSize = 0;
            for( int PointIndex = 0; PointIndex < GraphPoints.Count; PointIndex++ )
            {
                // Update progress bar.
                if( PointIndex >= NextProgressUpdate )
                {
                    OwnerWindow.ToolStripProgressBar.PerformStep();
                    NextProgressUpdate += ProgressInterval;
                    Debug.WriteLine( "FCallStackHistoryView.RenderSizeGraph " + OwnerWindow.ToolStripProgressBar.Value + "/20" );
                }

                FSizeGraphPoint SizeGraphPoint = GraphPoints[ PointIndex ];

                float X;
                if( bXAxisIsFrames )
                {
                    X = CalculateXForTime( ref NextFrame, SizeGraphPoint.StreamIndex ) * XScale - XBase;
                }
                else
                {
                    X = SizeGraphPoint.StreamIndex * XScale - XBase;
                }

                CurrentSize += SizeGraphPoint.SizeChange;

                float Y = CurrentSize * YScale;
                if( X >= 0 )
                {
                    if( X < GraphWidth )
                    {
                        MyGraphics.DrawLine( Pens.Black, OldX, GraphHeight - OldY, X, GraphHeight - OldY );
                        MyGraphics.DrawLine( Pens.Black, X, GraphHeight - OldY, X, GraphHeight - Y );
                    }
                    else
                    {
                        break;
                    }
                }

                OldPoint = SizeGraphPoint;
                OldX = X;
                OldY = Y;
            }

            // Connect final point to right edge of graph.
            if( bShouldCompleteGraph )
            {
                float FinalLineY = GraphHeight - OldY;
                MyGraphics.DrawLine( Pens.Black, OldX, FinalLineY, GraphWidth, FinalLineY );
            }

            OwnerWindow.ToolStripProgressBar.Visible = false;
        }