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; }