From 7d4b8a4cb686fea27d2b15a5dd9f18ff0fad3ed9 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 31 Oct 2009 18:36:04 +0000 Subject: [PATCH] Added event and time markers to extended timeline git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5201 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Misc/Profiler/Controller/Profiler.cs | 1 + .../Controls/ExtendedTimeLineControl.xaml.cs | 3 +- .../Frontend/Controls/TimeLineControl.cs | 89 +++++++++++++++---- src/AddIns/Misc/Profiler/Hook/Profiler.cpp | 6 +- src/AddIns/Misc/Profiler/Hook/constants.cpp | 4 +- src/AddIns/Misc/Profiler/Hook/global.h | 2 +- 6 files changed, 81 insertions(+), 24 deletions(-) diff --git a/src/AddIns/Misc/Profiler/Controller/Profiler.cs b/src/AddIns/Misc/Profiler/Controller/Profiler.cs index b24f532749..c558095d9e 100644 --- a/src/AddIns/Misc/Profiler/Controller/Profiler.cs +++ b/src/AddIns/Misc/Profiler/Controller/Profiler.cs @@ -50,6 +50,7 @@ namespace ICSharpCode.Profiler.Controller volatile bool stopDC; volatile bool enableDC; volatile bool isFirstDC; + volatile int millisecondsStartTime; /// /// Gets whether the profiler is running inside a 64-bit profilee process or not. diff --git a/src/AddIns/Misc/Profiler/Frontend/Controls/ExtendedTimeLineControl.xaml.cs b/src/AddIns/Misc/Profiler/Frontend/Controls/ExtendedTimeLineControl.xaml.cs index 48fcb4af07..4b015e7f05 100644 --- a/src/AddIns/Misc/Profiler/Frontend/Controls/ExtendedTimeLineControl.xaml.cs +++ b/src/AddIns/Misc/Profiler/Frontend/Controls/ExtendedTimeLineControl.xaml.cs @@ -39,6 +39,7 @@ namespace ICSharpCode.Profiler.Controls this.perfCounterList.ItemsSource = this.provider.GetPerformanceCounters(); this.perfCounterList.SelectedIndex = 0; + this.timeLine.Provider = provider; Update(); } @@ -84,7 +85,7 @@ namespace ICSharpCode.Profiler.Controls this.timeLine.Format = selectedPerformanceCounter.Format; for (int i = 0; i < values.Length; i++) - segments.Add(new TimeLineSegment() { Value = values[i], TimeOffset = 0, DisplayMarker = markers[i], Events = provider.GetEventDataEntries(i) }); + segments.Add(new TimeLineSegment() { Value = values[i], DisplayMarker = markers[i], Events = provider.GetEventDataEntries(i) }); this.timeLine.ValuesList.AddRange(segments); } diff --git a/src/AddIns/Misc/Profiler/Frontend/Controls/TimeLineControl.cs b/src/AddIns/Misc/Profiler/Frontend/Controls/TimeLineControl.cs index b5eb17aaa8..efc2770d0c 100644 --- a/src/AddIns/Misc/Profiler/Frontend/Controls/TimeLineControl.cs +++ b/src/AddIns/Misc/Profiler/Frontend/Controls/TimeLineControl.cs @@ -6,9 +6,11 @@ // using System; -using System.Collections.ObjectModel; +using System.Linq; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Diagnostics; +using System.Globalization; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; @@ -23,7 +25,6 @@ namespace ICSharpCode.Profiler.Controls public class TimeLineSegment { public float Value { get; set; } public bool DisplayMarker { get; set; } - public long TimeOffset { get; set; } public EventDataEntry[] Events { get; set; } } @@ -51,6 +52,8 @@ namespace ICSharpCode.Profiler.Controls public string Format { get; set; } + public ProfilingDataProvider Provider { get; set; } + public int SelectedEndIndex { get { return selectedEndIndex; } @@ -140,11 +143,23 @@ namespace ICSharpCode.Profiler.Controls drawingContext.DrawGeometry(b, new Pen(b, 1), geometry); + DateTime time = new DateTime(1,1,1,0,0,0,0); + for (int i = 0; i < this.valuesList.Count; i++) { if (this.valuesList[i].DisplayMarker) drawingContext.DrawLine(p, new Point(pieceWidth * i, offsetFromTop), new Point(pieceWidth * i, this.RenderSize.Height)); + if (i % 3 == 0) { + FormattedText textFormat = new FormattedText( + time.ToString("mm:ss.fff"), + CultureInfo.CurrentCulture, FlowDirection.LeftToRight, + new Typeface("Segoe UI"), 12, Brushes.Black + ); + + drawingContext.DrawText(textFormat, new Point(pieceWidth * i, 0)); + } + var events = this.valuesList[i].Events; if (events != null && events.Length > 0) { @@ -159,6 +174,8 @@ namespace ICSharpCode.Profiler.Controls ); } } + + time = time.AddMilliseconds(500); } drawingContext.DrawRectangle( @@ -174,16 +191,17 @@ namespace ICSharpCode.Profiler.Controls protected override void OnMouseUp(System.Windows.Input.MouseButtonEventArgs e) { bool valid; - int index = TransformToIndex(e.GetPosition(this), out valid); - - if (index < this.selectedStartIndex) { - this.selectedEndIndex = this.selectedStartIndex; - this.selectedStartIndex = index; - } else - this.selectedEndIndex = index; - - Console.WriteLine("start: {0} end: {1} count: {2}", SelectedStartIndex, SelectedEndIndex, valuesList.Count); + Point pos = e.GetPosition(this); + int index = TransformToIndex(pos, out valid); + if (pos.Y >= 40) { + if (index < this.selectedStartIndex) { + this.selectedEndIndex = this.selectedStartIndex; + this.selectedStartIndex = index; + } else + this.selectedEndIndex = index; + } + this.InvalidateMeasure(); this.InvalidateVisual(); this.ReleaseMouseCapture(); @@ -192,10 +210,12 @@ namespace ICSharpCode.Profiler.Controls protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e) { this.CaptureMouse(); + Point pos = e.GetPosition(this); bool valid; - int index = TransformToIndex(e.GetPosition(this), out valid); + int index = TransformToIndex(pos, out valid); - this.selectedStartIndex = this.selectedEndIndex = index; + if (pos.Y >= 40) + this.selectedStartIndex = this.selectedEndIndex = index; this.InvalidateMeasure(); this.InvalidateVisual(); @@ -216,14 +236,51 @@ namespace ICSharpCode.Profiler.Controls } else if (tooltip == null && valid) { tooltip = new ToolTip(); if (pos.Y < 20) - tooltip.Content = "Time: "; + tooltip.Content = "Time: " + new DateTime(0).AddMilliseconds(index * 500).ToString("mm:ss.fff"); else if (pos.Y < 40) - tooltip.Content = "Event: "; + tooltip.Content = CreateTooltipForEvents(index); else tooltip.Content = "Value: " + this.valuesList[index].Value.ToString(this.Format) + " " + this.Unit; - tooltip .IsOpen = true; + tooltip .IsOpen = tooltip.Content != null; } } + + object CreateTooltipForEvents(int index) + { + EventDataEntry[] events = this.ValuesList[index].Events; + + TextBlock block = events.Any() ? new TextBlock() : null; + + foreach (var e in events) { + if (block.Inlines.Any()) + block.Inlines.Add(new LineBreak()); + + NameMapping mapping = Provider.GetMapping(e.NameId); + string fullSignature = mapping.ReturnType + " " + mapping.Name + "(" + string.Join(", ", mapping.Parameters) + ")"; + block.Inlines.Add(new Bold { Inlines = { fullSignature } }); + + + switch (e.Type) { + case EventType.Console: + break; + case EventType.WindowsForms: + string target = e.Data.Substring(0, e.Data.IndexOf(':')); + string text = e.Data.Substring(e.Data.IndexOf(':') + 1); + block.Inlines.Add(new LineBreak()); + block.Inlines.Add(new Bold { Inlines = { "Source: " } }); + block.Inlines.Add(target); + block.Inlines.Add(new LineBreak()); + block.Inlines.Add(new Bold { Inlines = { "Text: " } }); + block.Inlines.Add(text); + break; + case EventType.Exception: + case EventType.WindowsPresentationFoundation: + break; + } + } + + return block; + } protected override void OnLostMouseCapture(MouseEventArgs e) { diff --git a/src/AddIns/Misc/Profiler/Hook/Profiler.cpp b/src/AddIns/Misc/Profiler/Hook/Profiler.cpp index eddf3f5b01..4105413d03 100644 --- a/src/AddIns/Misc/Profiler/Hook/Profiler.cpp +++ b/src/AddIns/Misc/Profiler/Hook/Profiler.cpp @@ -711,7 +711,6 @@ void CProfiler::Rewrite(FunctionID functionID, int type, int nameId) COR_ILMETHOD_TINY *method = (COR_ILMETHOD_TINY *)header; if (method->GetCodeSize() + sizeof(activateCall) + sizeof(loggerCall) + sizeof(deactivateCall) + 2 < MAX_CODE_SIZE_TINY) { - LogString(L"is tiny!"); // Copy the header elements. memcpy(&codeBuf[0], method, TINY_HEADER_SIZE); @@ -731,10 +730,9 @@ void CProfiler::Rewrite(FunctionID functionID, int type, int nameId) // 2 upper bits are the tiny header 6 lower bits are length codeBuf[0] = (byte)((newLength - 1) << 2 | 0x2); } else { - LogString(L"is tiny but exceeds!"); ConvertToFat((byte *)codeBuf, &newLength); - SetInjectionCode(metaData, codeBuf, &newLength, activateCall, loggerCall, deactivateCall, type, nameId); + SetInjectionCode(metaData, codeBuf, &newLength, activateCall, loggerCall, deactivateCall, type, nameId); // copy old code memcpy(&codeBuf[newLength], &header[TINY_HEADER_SIZE], length - TINY_HEADER_SIZE); @@ -744,8 +742,6 @@ void CProfiler::Rewrite(FunctionID functionID, int type, int nameId) target->CodeSize = newLength - FAT_HEADER_SIZE; } } else if (((COR_ILMETHOD_FAT *)header)->IsFat()) { - LogString(L"is fat!"); - COR_ILMETHOD_FAT *method = (COR_ILMETHOD_FAT *)header; COR_ILMETHOD_FAT *target = (COR_ILMETHOD_FAT *)codeBuf; diff --git a/src/AddIns/Misc/Profiler/Hook/constants.cpp b/src/AddIns/Misc/Profiler/Hook/constants.cpp index 09e70f4260..dae66ab3a0 100644 --- a/src/AddIns/Misc/Profiler/Hook/constants.cpp +++ b/src/AddIns/Misc/Profiler/Hook/constants.cpp @@ -14,7 +14,9 @@ WCHAR *consoleGroupList[CONSOLE_GROUP_LENGTH] = { WCHAR *winFormsGroupList[WINFORMS_GROUP_LENGTH] = { L"System.Windows.Forms.Control.OnClick", - L"System.Windows.Forms.Control.OnMouseClick" + L"System.Windows.Forms.Control.OnDoubleClick", + L"System.Windows.Forms.Control.OnMouseWheel", + L"System.Windows.Forms.Control.OnKeyDown" }; WCHAR *wpfGroupList[WPF_GROUP_LENGTH] = { diff --git a/src/AddIns/Misc/Profiler/Hook/global.h b/src/AddIns/Misc/Profiler/Hook/global.h index 75b7e8ccf3..2436015efd 100644 --- a/src/AddIns/Misc/Profiler/Hook/global.h +++ b/src/AddIns/Misc/Profiler/Hook/global.h @@ -14,7 +14,7 @@ #include "LightweightList.h" #define CONSOLE_GROUP_LENGTH 2 -#define WINFORMS_GROUP_LENGTH 2 +#define WINFORMS_GROUP_LENGTH 4 #define WPF_GROUP_LENGTH 1 extern fastAllocator stackAllocator;