コード例 #1
0
        public int FindNode(Point point, ThreadScroll scroll, out EventFrame eventFrame, out EventNode eventNode)
        {
            ITick tick = scroll.PixelToTime(point.X);

            int index = Data.Utils.BinarySearchExactIndex(EventData.Events, tick.Start);

            EventFrame resultFrame = null;
            EventNode  resultNode  = null;
            int        resultLevel = -1;

            if (index >= 0)
            {
                EventFrame frame = EventData.Events[index];

                int desiredLevel = (int)(point.Y / RenderParams.BaseHeight);

                GetTree(frame).ForEachChild((node, level) =>
                {
                    if (level > desiredLevel || resultFrame != null)
                    {
                        return(false);
                    }

                    if (level == desiredLevel)
                    {
                        EventNode evNode = (node as EventNode);
                        if (evNode.Entry.Intersect(tick.Start))
                        {
                            resultFrame = frame;
                            resultNode  = evNode;
                            resultLevel = level;
                            return(false);
                        }
                    }

                    return(true);
                });
            }

            eventFrame = resultFrame;
            eventNode  = resultNode;
            return(resultLevel);
        }
コード例 #2
0
ファイル: EventsThreadRow.cs プロジェクト: qjxkid/brofiler
        public override void OnMouseClick(Point point, ThreadScroll scroll)
        {
            EventNode  node  = null;
            EventFrame frame = null;
            int        level = FindNode(point, scroll, out frame, out node);

            if (EventNodeSelected != null)
            {
                ITick tick = scroll.PixelToTime(point.X);
                if (frame == null)
                {
                    frame = FindFrame(tick);
                }
                if (frame != null)
                {
                    EventNodeSelected(this, frame, node, tick);
                }
            }
        }
コード例 #3
0
ファイル: ThreadView.xaml.cs プロジェクト: vr3d/brofiler
        public void FocusOn(EventFrame frame, EventNode node)
        {
            if (!IsFrameVisible(frame))
            {
                double minRange = frame.Duration * FocusFrameExtent;
                if (Range < minRange)
                {
                    Range = minRange;
                }

                Position = Durable.TicksToMs(frame.Header.Start - timeRange.Start) + (frame.Duration - Range) / 2;
            }

            FocusedFrame = frame;
            FocusedNode  = node;

            UpdateBar();
            Refresh();
        }
コード例 #4
0
        void RenderFPSLines(System.Windows.Media.DrawingContext drawingContext, List <EventFrame> frames, KeyValuePair <int, int> interval)
        {
            double scale = AdornedElement.RenderSize.Width / Range;

            if (scale < RenderFPSLineLimit)
            {
                return;
            }

            double height = Extent.Height;

            StreamGeometry geometry = new StreamGeometry();

            using (StreamGeometryContext geometryContext = geometry.Open())
            {
                for (int i = interval.Key; i <= interval.Value; ++i)
                {
                    EventFrame frame = frames[i];

                    double posX  = (frame.Header.StartMS - timeRange.StartMS - Position) * scale;
                    Point  point = new Point(posX, fpsTriangleSize);
                    geometryContext.BeginFigure(point, true, true);
                    geometryContext.LineTo(new Point(posX - fpsTriangleSize / 2, 0), false, false);
                    geometryContext.LineTo(new Point(posX + fpsTriangleSize / 2, 0), false, false);

                    drawingContext.DrawLine(fpsPen, new Point(posX, 0), new Point(posX, height - SpaceHeight));

                    double maxTextWidth = Math.Max(frame.Duration * scale - 8, 0.0);

                    if (MaxDrawTextThreshold > maxTextWidth && maxTextWidth > MinDrawTextThreshold)
                    {
                        FormattedText text = new FormattedText(String.Format("{0:0.###}ms", frame.Duration).Replace(',', '.'), culture, FlowDirection.LeftToRight, fontDuration, 12, fpsBrush);
                        text.MaxLineCount = 1;
                        text.MaxTextWidth = maxTextWidth;
                        text.Trimming     = TextTrimming.None;
                        drawingContext.DrawText(text, new Point(posX + maxTextWidth / 2 - text.Width / 2, -2));
                    }
                }
            }

            drawingContext.DrawGeometry(fpsBrush, null, geometry);
        }
コード例 #5
0
ファイル: ThreadView.xaml.cs プロジェクト: wobbier/brofiler
        public void FocusOn(EventFrame frame, EventNode node)
        {
            Group = frame.Group;
            SelectionList.Clear();
            SelectionList.Add(new Selection()
            {
                Frame = frame, Node = node
            });

            Interval interval = scroll.TimeToUnit(node != null ? (IDurable)node.Entry : (IDurable)frame);

            if (!scroll.ViewUnit.Intersect(interval))
            {
                scroll.ViewUnit.Width = interval.Width * DefaultFrameZoom;
                scroll.ViewUnit.Left  = interval.Left - (scroll.ViewUnit.Width - interval.Width) * 0.5;
                scroll.ViewUnit.Normalize();
                UpdateBar();
            }

            UpdateSurface();
        }
コード例 #6
0
        private void Flush()
        {
            EventDescription desc = FunctionSearchDataGrid.SelectedItem as EventDescription;

            if (desc != null)
            {
                if (Group != null)
                {
                    double     maxDuration = 0;
                    EventFrame maxFrame    = null;
                    Entry      maxEntry    = null;

                    foreach (ThreadData thread in Group.Threads)
                    {
                        foreach (EventFrame frame in thread.Events)
                        {
                            List <Entry> entries = null;
                            if (frame.ShortBoard.TryGetValue(desc, out entries))
                            {
                                foreach (Entry entry in entries)
                                {
                                    if (entry.Duration > maxDuration)
                                    {
                                        maxFrame    = frame;
                                        maxEntry    = entry;
                                        maxDuration = entry.Duration;
                                    }
                                }
                            }
                        }
                    }

                    if (maxFrame != null && maxEntry != null)
                    {
                        EventNode maxNode = maxFrame.Root.FindNode(maxEntry);
                        RaiseEvent(new TimeLine.FocusFrameEventArgs(TimeLine.FocusFrameEvent, new EventFrame(maxFrame, maxNode), null));
                    }
                }
            }
        }
コード例 #7
0
        private void SampleFunction(EventFrame eventFrame, EventNode node, bool single)
        {
            List <Callstack> callstacks = new List <Callstack>();
            FrameGroup       group      = eventFrame.Group;

            if (single)
            {
                Utils.ForEachInsideIntervalStrict(group.Threads[eventFrame.Header.ThreadIndex].Callstacks, node.Entry, callstack => callstacks.Add(callstack));
            }
            else
            {
                EventDescription desc = node.Entry.Description;

                foreach (ThreadData thread in group.Threads)
                {
                    HashSet <Callstack> accumulator = new HashSet <Callstack>();
                    foreach (EventFrame currentFrame in thread.Events)
                    {
                        List <Entry> entries = null;
                        if (currentFrame.ShortBoard.TryGetValue(desc, out entries))
                        {
                            foreach (Entry entry in entries)
                            {
                                Utils.ForEachInsideIntervalStrict(thread.Callstacks, entry, c => accumulator.Add(c));
                            }
                        }
                    }

                    callstacks.AddRange(accumulator);
                }
            }


            if (callstacks.Count > 0)
            {
                SamplingFrame frame = new SamplingFrame(callstacks);
                Profiler.TimeLine.FocusFrameEventArgs args = new Profiler.TimeLine.FocusFrameEventArgs(Profiler.TimeLine.FocusFrameEvent, frame);
                RaiseEvent(args);
            }
        }
コード例 #8
0
 private void ApplyDescriptionFilterToFramesTimeLine(HashSet <Object> filter)
 {
     Application.Current.Dispatcher.BeginInvoke(new Action(() =>
     {
         foreach (Data.Frame frame in frames)
         {
             EventFrame eventFrame = frame as EventFrame;
             if (eventFrame != null)
             {
                 if (filter == null)
                 {
                     eventFrame.FilteredDescription = "";
                 }
                 else
                 {
                     double timeInMs = eventFrame.CalculateFilteredTime(filter);
                     eventFrame.FilteredDescription = String.Format("{0:0.000}", timeInMs);
                 }
             }
         }
     }));
 }
コード例 #9
0
        void InitThreadList(SamplingFrame frame)
        {
            Frame = frame;

            List <ThreadRow> rows = new List <ThreadRow>();

            if (frame != null)
            {
                List <Entry> entries = new List <Entry>();

                SamplingNode root = frame.Root;

                BuildEntryList(entries, root, 0.0);

                EventFrame eventFrame = new EventFrame(new FrameHeader()
                {
                    Start = 0, Finish = Durable.MsToTick(root.Duration)
                }, entries, frame.Group);
                ThreadData threadData = new ThreadData(null)
                {
                    Events = new List <EventFrame> {
                        eventFrame
                    }
                };
                EventsThreadRow row = new EventsThreadRow(frame.Group, new ThreadDescription()
                {
                    Name = "Sampling Node"
                }, threadData, Settings);
                row.LimitMaxDepth   = false;
                row.EventNodeHover += Row_EventNodeHover;
                rows.Add(row);
                ThreadViewControl.Scroll.ViewUnit.Width = 1.0;
                ThreadViewControl.InitRows(rows, eventFrame.Header);
            }
            else
            {
                ThreadViewControl.InitRows(rows, null);
            }
        }
コード例 #10
0
        private void OpenFrame(object source, FocusFrameEventArgs args)
        {
            Data.Frame frame = args.Frame;

            if (frame is EventFrame)
            {
                EventThreadViewControl.Highlight(frame as EventFrame, null);
            }

            if (frame is EventFrame)
            {
                EventFrame eventFrame = frame as EventFrame;
                FrameGroup group      = eventFrame.Group;

                if (eventFrame.RootEntry != null)
                {
                    EventDescription desc = eventFrame.RootEntry.Description;

                    FunctionSummaryVM.Load(group, desc);
                    FunctionInstanceVM.Load(group, desc);

                    FunctionSamplingVM.Load(group, desc);
                    SysCallsSamplingVM.Load(group, desc);

                    FrameInfoControl.SetFrame(frame, null);
                }
            }

            if (frame != null && frame.Group != null)
            {
                if (!ReferenceEquals(SummaryVM.Summary, frame.Group.Summary))
                {
                    SummaryVM.Summary     = frame.Group.Summary;
                    SummaryVM.CaptureName = _captureName;
                }
            }
        }
コード例 #11
0
        public override void OnMouseHover(Point point, ThreadScroll scroll, List <object> dataContext)
        {
            EventNode  node  = null;
            EventFrame frame = null;

            ITick tick = scroll.PixelToTime(point.X);

            if (FindNode(point, scroll, out frame, out node) != -1)
            {
                dataContext.Add(node);
            }

            // show current sync info
            if (EventData.Sync != null && EventData.Sync != null)
            {
                int index = Data.Utils.BinarySearchClosestIndex(EventData.Sync, tick.Start);
                if (index != -1)
                {
                    bool         insideWaitInterval = false;
                    WaitInterval interval           = new WaitInterval()
                    {
                        Start = EventData.Sync[index].Finish, Reason = EventData.Sync[index].Reason
                    };
                    if (index + 1 < EventData.Sync.Count)
                    {
                        if (EventData.Sync[index].Finish < tick.Start && tick.Start < EventData.Sync[index + 1].Start)
                        {
                            UInt64 threadId = EventData.Sync[index].NewThreadId;

                            ThreadDescription threadDesc = null;
                            Group.Board.ThreadDescriptions.TryGetValue(threadId, out threadDesc);

                            interval.newThreadDesc = threadDesc;
                            interval.newThreadId   = threadId;

                            interval.Finish = EventData.Sync[index + 1].Start;
                            dataContext.Add(interval);
                            insideWaitInterval = true;
                        }
                    }

                    if (!insideWaitInterval)
                    {
                        interval.Reason = SyncReason.SyncReasonActive;
                        interval.Start  = EventData.Sync[index].Start;
                        interval.Finish = EventData.Sync[index].Finish;
                        interval.core   = (byte)EventData.Sync[index].Core;
                        dataContext.Add(interval);
                    }
                }
            }

            if (node != null)
            {
                // build all intervals inside selected node
                int from = Data.Utils.BinarySearchClosestIndex(frame.Synchronization, node.Entry.Start);
                int to   = Data.Utils.BinarySearchClosestIndex(frame.Synchronization, node.Entry.Finish);

                if (from >= 0 && to >= from)
                {
                    IntPair[] waitInfo = new IntPair[(int)SyncReason.SyncReasonCount];

                    for (int index = from; index <= to; ++index)
                    {
                        SyncReason reason      = frame.Synchronization[index].Reason;
                        int        reasonIndex = (int)reason;

                        long idleStart  = frame.Synchronization[index].Finish;
                        long idleFinish = (index + 1 < frame.Synchronization.Count) ? frame.Synchronization[index + 1].Start : frame.Finish;

                        if (idleStart > node.Entry.Finish)
                        {
                            continue;
                        }

                        long idleStartClamped  = Math.Max(idleStart, node.Entry.Start);
                        long idleFinishClamped = Math.Min(idleFinish, node.Entry.Finish);
                        long durationInTicks   = idleFinishClamped - idleStartClamped;
                        waitInfo[reasonIndex].duration += durationInTicks;
                        waitInfo[reasonIndex].count++;
                    }

                    NodeWaitIntervalList intervals = new NodeWaitIntervalList();

                    for (int i = 0; i < waitInfo.Length; i++)
                    {
                        if (waitInfo[i].count > 0)
                        {
                            NodeWaitInterval interval = new NodeWaitInterval()
                            {
                                Start = 0, Finish = waitInfo[i].duration, Reason = (SyncReason)i, NodeInterval = node.Entry, Count = waitInfo[i].count
                            };
                            intervals.Add(interval);
                        }
                    }

                    intervals.Sort((a, b) =>
                    {
                        return(Comparer <long> .Default.Compare(b.Finish, a.Finish));
                    });

                    if (intervals.Count > 0)
                    {
                        dataContext.Add(intervals);
                    }
                }
            }             // FindNode

            if (EventData.Callstacks != null && scroll.DrawCallstacks != 0)
            {
                int startIndex = Data.Utils.BinarySearchClosestIndex(EventData.Callstacks, tick.Start);

                for (int i = startIndex; (i <= startIndex + 1) && (i < EventData.Callstacks.Count) && (i != -1); ++i)
                {
                    double pixelPos = scroll.TimeToPixel(EventData.Callstacks[i]);
                    if (Math.Abs(pixelPos - point.X) < CallstackMarkerRadius * 1.2 && (EventData.Callstacks[i].Reason & scroll.DrawCallstacks) != 0)
                    {
                        dataContext.Add(EventData.Callstacks[i]);
                        break;
                    }
                }
            }
        }
コード例 #12
0
 public void FocusOn(EventFrame frame, EventNode node)
 {
     Group = frame.Group;
     canvas.FocusOn(frame, node);
 }
コード例 #13
0
 EventTree GetTree(EventFrame frame)
 {
     return(frame.Root);
 }
コード例 #14
0
 private void Row_EventNodeSelected(ThreadRow row, EventFrame frame, EventNode node, ITick tick)
 {
     RaiseEvent(new TimeLine.FocusFrameEventArgs(TimeLine.FocusFrameEvent, frame, node, tick));
 }
コード例 #15
0
        public override object Deserialize(IDictionary <string, object> dictionary, Type type, JavaScriptSerializer serializer)
        {
            if (type == typeof(TimelineDelta))
            {
                var obj = new TimelineDelta();
                if (dictionary.ContainsKey("0-10"))
                {
                    obj.StartToTen = serializer.ConvertToType <float>(dictionary["0-10"]);
                }
                if (dictionary.ContainsKey("10-20"))
                {
                    obj.TenToTwenty = serializer.ConvertToType <float>(dictionary["10-20"]);
                }
                if (dictionary.ContainsKey("20-30"))
                {
                    obj.TwentyToThirty = serializer.ConvertToType <float>(dictionary["20-30"]);
                }
                if (dictionary.ContainsKey("30-end"))
                {
                    obj.ThirtyToEnd = serializer.ConvertToType <float>(dictionary["30-end"]);
                }
                return(obj);
            }

            if (type == typeof(ParticipantFrames))
            {
                var obj = new ParticipantFrames();

                obj.frames = new List <ParticipantFrame>();
                foreach (KeyValuePair <string, object> pair in dictionary)
                {
                    obj.frames.Add(serializer.ConvertToType <ParticipantFrame>(pair.Value));
                }

                return(obj);
            }

            if (type == typeof(EventFrame))
            {
                var obj = new EventFrame();
                if (dictionary.ContainsKey("type"))
                {
                    if ("WARD_PLACED" == (string)dictionary["type"])
                    {
                        return(GetTypeFromDictionary <WardPlacedFrame>(dictionary, serializer));
                    }
                    else if ("WARD_KILL" == (string)dictionary["type"])
                    {
                        return(GetTypeFromDictionary <WardKillFrame>(dictionary, serializer));
                    }
                    else if ("ELITE_MONSTER_KILL" == (string)dictionary["type"])
                    {
                        return(GetTypeFromDictionary <EliteMonsterKillFrame>(dictionary, serializer));
                    }
                    else if ("CHAMPION_KILL" == (string)dictionary["type"])
                    {
                        return(GetTypeFromDictionary <ChampionKillFrame>(dictionary, serializer));
                    }
                    else if ("BUILDING_KILL" == (string)dictionary["type"])
                    {
                        return(GetTypeFromDictionary <BuildingKillFrame>(dictionary, serializer));
                    }
                }

                //Unknown type?
                return(obj);
            }

            return(null);
        }
コード例 #16
0
        bool IsFrameVisible(EventFrame frame)
        {
            double framePos = frame.Header.StartMS - timeRange.StartMS;

            return(Position < framePos && framePos < Position + Range);
        }
コード例 #17
0
        void OnRenderFrame(System.Windows.Media.DrawingContext drawingContext, EventFrame frame, double rowOffset, int maxDepth, Brush backgroundBrush)
        {
            Rect rectangle = CalculateRect(frame.Header, rowOffset, maxDepth * BlockHeight);

            if (rectangle.Width < MinDrawFrameThreshold)
            {
                return;
            }

            bool   isFilterReady = false;
            double filteredValue = 0.0;

            if (Filter != null)
            {
                isFilterReady = Filter.TryGetFilteredFrameTime(frame, out filteredValue);
            }

            //drawingContext.DrawRectangle(Filter != null && isFilterReady ? Brushes.LimeGreen : Brushes.Gray, null, rectangle);

            if (Filter == null)
            {
                List <KeyValuePair <Entry, Rect> > rects = new List <KeyValuePair <Entry, Rect> >();

                foreach (EventNode node in frame.CategoriesTree.Children)
                {
                    GenerateEventNode(node, rectangle, 0, maxDepth, rects);
                }

                if (rects.Count > 0 || frame.Synchronization.Count > 0)
                {
                    foreach (var item in rects)
                    {
                        if (brushes.ContainsKey(item.Key.Description.Color) == false)
                        {
                            UInt32 color    = item.Key.Description.Color;
                            var    sysColor = Color.FromArgb((byte)(color >> 24),
                                                             (byte)(color >> 16),
                                                             (byte)(color >> 8),
                                                             (byte)(color));
                            var brush = new SolidColorBrush(sysColor);
                            brushes.Add(color, brush);
                        }
                        drawingContext.DrawRectangle(brushes[item.Key.Description.Color], borderPen, item.Value);
                    }

                    foreach (EventData entry in frame.Synchronization)
                    {
                        Rect rect = CalculateRect(entry, rowOffset, SyncLineHeight);
                        if (rect.Width > DrawThreshold)
                        {
                            drawingContext.DrawRectangle(Brushes.OrangeRed, null, rect);
                        }
                    }

                    foreach (var item in rects)
                    {
                        if (item.Value.Width < MinDrawTextThreshold || item.Value.Width > MaxDrawTextThreshold)
                        {
                            continue;
                        }

                        FormattedText categoryText = new FormattedText(item.Key.Description.Name, culture, FlowDirection.LeftToRight, fontCategoryName, 11, Brushes.Black, null, TextFormattingMode.Display);
                        categoryText.MaxTextWidth = item.Value.Width - textOffset.X;
                        categoryText.Trimming     = TextTrimming.None;
                        categoryText.MaxLineCount = 1;
                        drawingContext.DrawText(categoryText, item.Value.Location + textOffset);
                    }
                }
            }

            if (rectangle.Width > DrawThreshold)
            {
                drawingContext.DrawRectangle(null, borderPen, rectangle);

                double value = frame.Duration;

                if (Filter != null)
                {
                    if (isFilterReady)
                    {
                        double ratio = filteredValue / frame.Duration;
                        value = filteredValue;
                        drawingContext.DrawRectangle(Brushes.Tomato, null, new Rect(rectangle.X, rectangle.Y, rectangle.Width * ratio, rectangle.Height));
                    }
                }

                if (Filter != null)
                {
                    FormattedText timingText = new FormattedText(String.Format("{0:0.###}ms", value).Replace(',', '.'), culture, FlowDirection.LeftToRight, fontDuration, 12, Brushes.Black);
                    timingText.MaxTextWidth = rectangle.Width;
                    timingText.MaxLineCount = 1;
                    timingText.Trimming     = TextTrimming.None;

                    Point point = new Point(rectangle.Left + 1, rectangle.Bottom - timingText.Height + 1);
                    drawingContext.DrawText(timingText, point);
                }
            }
        }
コード例 #18
0
 EventTree GetTree(EventFrame frame)
 {
     return(IsExpanded ? frame.Root : frame.CategoriesTree);
 }