void DrawSelection(DirectX.DirectXCanvas canvas) { foreach (Selection selection in SelectionList) { if (selection.Frame != null) { ThreadRow row = id2row[selection.Frame.Header.ThreadIndex]; Durable intervalTime = selection.Node == null ? (Durable)selection.Frame.Header : (Durable)selection.Node.Entry; Interval intervalPx = scroll.TimeToPixel(intervalTime); Rect rect = new Rect(intervalPx.Left, row.Offset + 2.0 * RenderParams.BaseMargin, intervalPx.Width, row.Height - 4.0 * RenderParams.BaseMargin); for (int i = 0; i < SelectionBorderCount; ++i) { rect.Inflate(SelectionBorderStep, SelectionBorderStep); SelectionMesh.AddRect(rect, FrameSelection.Color); } } } SelectionMesh.Update(canvas.RenderDevice); canvas.Draw(SelectionMesh); }
public override void BuildMesh(DirectX.DirectXCanvas canvas, ThreadScroll scroll) { SetBusy(true); UpdateDepth(); // Build Mesh DirectX.ComplexDynamicMesh builder = new ComplexDynamicMesh(canvas, DIPSplitCount); DirectX.ComplexDynamicMesh syncBuilder = new ComplexDynamicMesh(canvas, DIPSplitCount); DirectX.ComplexDynamicMesh syncWorkBuilder = new ComplexDynamicMesh(canvas, DIPSplitCount); if (EventData.Sync != null && EventData.Sync != null) { SyncReason stallReason = SyncReason.SyncReasonCount; long stallFrom = 0; int frameSyncIndex = 0; for (int i = 0; i < EventData.Sync.Count; i++) { SyncInterval sync = EventData.Sync[i]; Interval workInterval = scroll.TimeToUnit(sync); //draw work int coreColorIndex = (int)sync.Core; coreColorIndex = coreColorIndex % WorkColors.Length; Color WorkColor = WorkColors[coreColorIndex]; syncWorkBuilder.AddRect(new Rect(workInterval.Left, 0, workInterval.Right - workInterval.Left, SyncLineHeight / Height), WorkColor); if (i == 0) { stallReason = sync.Reason; stallFrom = sync.Finish; continue; } long workStart = sync.Start; long workFinish = sync.Finish; while (frameSyncIndex < EventData.Events.Count && EventData.Events[frameSyncIndex].Finish < stallFrom) { ++frameSyncIndex; } //Ignoring all the waiting outside marked work to simplify the view if (frameSyncIndex < EventData.Events.Count && EventData.Events[frameSyncIndex].Start <= workStart) { Durable syncDurable = new Durable(stallFrom, workStart); Interval syncInterval = scroll.TimeToUnit(syncDurable); double syncWidth = syncInterval.Right - syncInterval.Left; if (syncWidth > 0) { // draw sleep Color waitColor = IsUserInitiatedSync(stallReason) ? SynchronizationColorUser : SynchronizationColor; syncBuilder.AddRect(new Rect(syncInterval.Left, 0, syncWidth, SyncLineHeight / Height), waitColor); } } stallFrom = workFinish; stallReason = sync.Reason; } } foreach (EventFrame frame in EventData.Events) { Durable interval = Group.Board.TimeSlice; EventTree tree = GetTree(frame); foreach (EventNode node in tree.Children) { BuildMeshNode(builder, scroll, node, 0); } } Blocks = builder.Freeze(canvas.RenderDevice); SyncMesh = syncBuilder.Freeze(canvas.RenderDevice); SyncWorkMesh = syncWorkBuilder.Freeze(canvas.RenderDevice); CallstackMeshPolys = canvas.CreateMesh(); CallstackMeshPolys.Projection = Mesh.ProjectionType.Pixel; CallstackMeshLines = canvas.CreateMesh(); CallstackMeshLines.Geometry = Mesh.GeometryType.Lines; CallstackMeshLines.Projection = Mesh.ProjectionType.Pixel; SetBusy(false); }
public InputState() { MeasureInterval = new Durable(); }
void BuildEntryList(List <Entry> entries, SamplingNode node, double offset) { if (node.Description != null) { entries.Add(new Entry(new EventDescription(node.NameWithModule), Durable.MsToTick(offset), Durable.MsToTick(offset + node.Duration))); } offset += node.SelfDuration * 0.5; foreach (SamplingNode child in node.Children) { BuildEntryList(entries, child, offset); offset += child.Duration; } }
private void OpenTab(object source, TimeLine.FocusFrameEventArgs args) { Durable focusRange = null; if (args.Node != null) { focusRange = args.Node.Entry; } else if (args.Tick != null) { focusRange = new Durable(args.Tick.Start, args.Tick.Start + 1); } else if (args.Frame is EventFrame) { focusRange = (args.Frame as EventFrame).Header; } Data.Frame frame = args.Frame; foreach (var tab in frameTabs.Items) { if (tab is CloseableTabItem) { CloseableTabItem item = (CloseableTabItem)tab; if (item.DataContext.Equals(frame)) { frameTabs.SelectedItem = item; if (item.frameInfo != null) { item.frameInfo.FocusOnNode(focusRange); } return; } } } /* * CloseableTabItem curr = frameTabs.SelectedItem as CloseableTabItem; * string currFiltredText = null; * if (curr != null && curr.frameInfo != null) * { * currFiltredText = curr.frameInfo.SummaryTable.FilterText.FilterText.Text; * } */ CloseableTabItem tabItem = new CloseableTabItem() { Header = "Loading...", DataContext = frame }; FrameInfo info = new FrameInfo(timeLine.Frames) { Height = Double.NaN, Width = Double.NaN, DataContext = null }; info.DataContextChanged += new DependencyPropertyChangedEventHandler((object sender, DependencyPropertyChangedEventArgs e) => { tabItem.Header = frame.Description; }); info.SelectedTreeNodeChanged += new SelectedTreeNodeChangedHandler(FrameInfo_OnSelectedTreeNodeChanged); info.SetFrame(frame); tabItem.AddFrameInfo(info); frameTabs.Items.Add(tabItem); frameTabs.SelectedItem = tabItem; info.FocusOnNode(focusRange); /* * if (!string.IsNullOrEmpty(currFiltredText)) * { * info.SummaryTable.FilterText.SetFilterText(currFiltredText); * } */ }
public override void BuildMesh(DirectX.DirectXCanvas canvas, ThreadScroll scroll) { // Build Mesh DirectX.DynamicMesh builder = canvas.CreateMesh(); DirectX.DynamicMesh syncBuilder = canvas.CreateMesh(); if (EventData.Sync != null && EventData.Sync.Intervals != null) { SyncReason stallReason = SyncReason.SyncReasonCount; long stallFrom = 0; for (int i = 0; i < EventData.Sync.Intervals.Count; i++) { SyncInterval sync = EventData.Sync.Intervals[i]; Interval workInterval = scroll.TimeToUnit(sync); // draw work int coreColorIndex = (int)sync.Core; coreColorIndex = coreColorIndex % WorkColors.Length; Color WorkColor = WorkColors[coreColorIndex]; syncBuilder.AddRect(new Rect(workInterval.Left, RenderParams.BaseMargin / Height, workInterval.Right - workInterval.Left, SyncLineHeight / Height), WorkColor); if (i == 0) { stallReason = sync.Reason; stallFrom = sync.Finish; continue; } long workStart = sync.Start; long workFinish = sync.Finish; Interval syncInterval = scroll.TimeToUnit(new Durable(stallFrom, workStart)); double syncWidth = syncInterval.Right - syncInterval.Left; if (syncWidth <= 0) { syncWidth = 0.1; } // draw sleep Color waitColor = IsUserInitiatedSync(stallReason) ? SynchronizationColorUser : SynchronizationColor; syncBuilder.AddRect(new Rect(syncInterval.Left, RenderParams.BaseMargin / Height, syncWidth, SyncLineHeight / Height), waitColor); stallFrom = workFinish; stallReason = sync.Reason; } } foreach (EventFrame frame in EventData.Events) { Durable interval = Group.Board.TimeSlice; foreach (EventNode node in frame.CategoriesTree.Children) { BuildMeshNode(builder, scroll, node, 0); } } Mesh = builder.Freeze(canvas.RenderDevice); SyncMesh = syncBuilder.Freeze(canvas.RenderDevice); CallstackMeshPolys = canvas.CreateMesh(); CallstackMeshLines = canvas.CreateMesh(); CallstackMeshLines.Geometry = Mesh.GeometryType.Lines; }
public bool FocusOnNode(Durable focusRange) { if (EventTreeView == null) { return(false); } if (EventTreeView.ItemsSource == null) { return(false); } List <BaseTreeNode> treePath = new List <BaseTreeNode>(); foreach (var node in EventTreeView.ItemsSource) { BaseTreeNode baseTreeNode = node as BaseTreeNode; if (baseTreeNode == null) { continue; } baseTreeNode.ForEach((curNode, level) => { EventNode treeEventNode = curNode as EventNode; if (treeEventNode == null) { return(true); } if (treeEventNode.Entry.Start > focusRange.Finish) { return(false); } if (treeEventNode.Entry.Intersect(focusRange)) { treePath.Add(curNode); //find desired node in tree if (treeEventNode.Entry.Start >= focusRange.Start && treeEventNode.Entry.Finish <= focusRange.Finish) { return(false); } } return(true); }); ItemsControl root = EventTreeView; int pathElementsCount = treePath.Count; if (pathElementsCount > 0) { //expand path in tree int index = 0; for (index = 0; index < (pathElementsCount - 1); index++) { BaseTreeNode expandNode = treePath[index]; if (root != null) { root = root.ItemContainerGenerator.ContainerFromItem(expandNode) as ItemsControl; } treePath[index].IsExpanded = true; } BaseTreeNode finalNode = treePath[index]; // select target node finalNode.IsExpanded = false; finalNode.IsSelected = true; // focus on finalNode if (root != null) { root = root.ItemContainerGenerator.ContainerFromItem(finalNode) as ItemsControl; if (root != null) { root.BringIntoView(); } } EventTreeView.InvalidateVisual(); return(true); } } return(false); }
Rect CalculateRect(Durable time, double rowOffset, double height) { double scale = AdornedElement.RenderSize.Width / Range; return(new Rect((time.StartMS - timeRange.StartMS - Position) * scale, rowOffset, time.Duration * scale, height)); }
protected override void OnRender(System.Windows.Media.DrawingContext drawingContext) { if (group == null) { return; } Rect area = new Rect(0, 0, AdornedElement.RenderSize.Width, AdornedElement.RenderSize.Height); drawingContext.PushClip(new RectangleGeometry(area)); drawingContext.DrawRectangle(Brushes.White, null, area); var threads = group.Threads; int rowIndex = 0; KeyValuePair <int, int> mainThreadInterval = new KeyValuePair <int, int>(); for (int threadIndex = 0; threadIndex < threads.Count; ++threadIndex) { List <EventFrame> frames = threads[threadIndex].Events; RowRange rowRange = rows[threadIndex]; if (rowRange.MaxDepth > 0 && frames.Count > 0) { KeyValuePair <int, int> interval = CalculateEventRange(frames, Position, Position + Range); if (threadIndex == group.Board.MainThreadIndex) { mainThreadInterval = interval; } Brush backgroundBrush = Brushes.White; if (rowIndex++ % 2 == 0) { backgroundBrush = AlternativeBackgroundColor; drawingContext.DrawRectangle(AlternativeBackgroundColor, null, new Rect(0, rowRange.Offset, AdornedElement.RenderSize.Width, rowRange.Height)); } for (int i = interval.Key; i <= interval.Value; ++i) { OnRenderFrame(drawingContext, frames[i], rowRange.Offset, rowRange.MaxDepth, backgroundBrush); } } } int mainThreadIndex = group.Board.MainThreadIndex; RenderFPSLines(drawingContext, group.Threads[mainThreadIndex].Events, mainThreadInterval); if (FocusedFrame != null) { RowRange rowRange = rows[FocusedFrame.Header.ThreadIndex]; Durable interval = FocusedNode != null ? FocusedNode.Entry as Durable : FocusedFrame.Header as Durable; Rect focusedRectangle = CalculateRect(interval, rowRange.Offset, rowRange.Height); drawingContext.DrawRectangle(null, selectedPen, focusedRectangle); } RenderSelectedScopes(drawingContext); drawingContext.Pop(); base.OnRender(drawingContext); }
public Interval TimeToUnit(Durable d) { double durationTicks = TimeSlice.Finish - TimeSlice.Start; return(new Interval((d.Start - TimeSlice.Start) / durationTicks, (d.Finish - d.Start) / durationTicks)); }