예제 #1
0
        public override void Update(GameTime gameTime)
        {
            if (dumpTiming.ElapsedMilliseconds > 500)
            {
                dumpTiming.Restart();
            }
            else
            {
                return;
            }

            if (stringBuilderTask != null && !stringBuilderTask.IsCompleted)
            {
                return;
            }

            stringBuilderTask = new Task(() =>
            {
                //Advance any profiler that needs it
                gcProfiler.Tick();

                //Copy events from profiler ( this will also clean up the profiler )
                //todo do we really need this copy?
                var eventsCopy = Profiler.GetEvents();
                if (eventsCopy == null)
                {
                    return;
                }

                var elapsedTime = eventsCopy.Length > 0 ? eventsCopy[eventsCopy.Length - 1].TimeStamp - eventsCopy[0].TimeStamp : 0;

                //update strings that need update
                foreach (var e in eventsCopy)
                {
                    //gc profiling is a special case
                    if (e.Key == GcProfiling.GcMemoryKey && e.Custom0.HasValue && e.Custom1.HasValue && e.Custom2.HasValue)
                    {
                        gcMemoryStringBuilder.Clear();
                        gcMemoryStringBuilder.AppendFormat(gcMemoryStringBase, e.Custom0.Value.LongValue, e.Custom2.Value.LongValue, e.Custom1.Value.LongValue);
                        continue;
                    }

                    if (e.Key == GcProfiling.GcCollectionCountKey && e.Custom0.HasValue && e.Custom1.HasValue && e.Custom2.HasValue)
                    {
                        gcCollectionsStringBuilder.Clear();
                        gcCollectionsStringBuilder.AppendFormat(gcCollectionsStringBase, e.Custom0.Value.IntValue, e.Custom1.Value.IntValue, e.Custom2.Value.IntValue);
                        continue;
                    }

                    if (e.Key == GameProfilingKeys.GameDrawFPS && e.Type == ProfilingMessageType.End)
                    {
                        fpsStatStringBuilder.Clear();
                        fpsStatStringBuilder.AppendFormat(e.Text, e.Custom0.Value.IntValue, e.Custom1.Value.DoubleValue, e.Custom2.Value.DoubleValue, e.Custom3.Value.FloatValue);
                        continue;
                    }

                    ProfilingResult profilingResult;
                    if (!profilingResultsDictionary.TryGetValue(e.Key, out profilingResult))
                    {
                        profilingResult.MinTime = long.MaxValue;
                    }

                    if (e.Type == ProfilingMessageType.End)
                    {
                        profilingResult.AccumulatedTime += e.ElapsedTime;

                        if (e.ElapsedTime < profilingResult.MinTime)
                        {
                            profilingResult.MinTime = e.ElapsedTime;
                        }
                        if (e.ElapsedTime > profilingResult.MaxTime)
                        {
                            profilingResult.MaxTime = e.ElapsedTime;
                        }

                        profilingResult.Event = e;
                    }
                    else if (e.Type == ProfilingMessageType.Mark) // counter incremented only Mark!
                    {
                        profilingResult.Count++;
                    }

                    if (e.Custom0.HasValue)
                    {
                        profilingResult.Custom0 = e.Custom0.Value;
                    }
                    if (e.Custom1.HasValue)
                    {
                        profilingResult.Custom1 = e.Custom1.Value;
                    }
                    if (e.Custom2.HasValue)
                    {
                        profilingResult.Custom2 = e.Custom2.Value;
                    }
                    if (e.Custom3.HasValue)
                    {
                        profilingResult.Custom3 = e.Custom3.Value;
                    }

                    if (e.Key == MicroThreadProfilingKeys.ProfilingKey)
                    {
                        scriptsProfilingResultsDictionary[e.Text] = profilingResult;
                    }
                    else
                    {
                        profilingResultsDictionary[e.Key] = profilingResult;
                    }
                }

                profilersStringBuilder.Clear();
                profilingResults.Clear();

                foreach (var profilingResult in profilingResultsDictionary)
                {
                    if (!profilingResult.Value.Event.HasValue)
                    {
                        continue;
                    }
                    profilingResults.Add(profilingResult.Value);
                }

                profilingResultsDictionary.Clear();

                if (SortingMode == GameProfilingSorting.ByTime)
                {
                    profilingResults.Sort((x1, x2) => Math.Sign(x2.AccumulatedTime - x1.AccumulatedTime));
                }
                else
                {
                    // Can't be null because we skip those events without values
                    // ReSharper disable PossibleInvalidOperationException
                    profilingResults.Sort((x1, x2) => string.Compare(x1.Event.Value.Key.Name, x2.Event.Value.Key.Name, StringComparison.Ordinal));
                    // ReSharper restore PossibleInvalidOperationException
                }

                foreach (var result in profilingResults)
                {
                    AppendEvent(result, result.Event.Value, elapsedTime);
                }

                profilingResults.Clear();

                foreach (var profilingResult in scriptsProfilingResultsDictionary)
                {
                    if (!profilingResult.Value.Event.HasValue)
                    {
                        continue;
                    }
                    profilingResults.Add(profilingResult.Value);
                }

                scriptsProfilingResultsDictionary.Clear();

                if (SortingMode == GameProfilingSorting.ByTime)
                {
                    profilingResults.Sort((x1, x2) => Math.Sign(x2.AccumulatedTime - x1.AccumulatedTime));
                }
                else
                {
                    // Can't be null because we skip those events without values
                    // ReSharper disable PossibleInvalidOperationException
                    profilingResults.Sort((x1, x2) => string.Compare(x1.Event.Value.Key.Name, x2.Event.Value.Key.Name, StringComparison.Ordinal));
                    // ReSharper restore PossibleInvalidOperationException
                }

                foreach (var result in profilingResults)
                {
                    AppendEvent(result, result.Event.Value, elapsedTime);
                }

                lock (stringLock)
                {
                    gcCollectionsString = gcCollectionsStringBuilder.ToString();
                    gcMemoryString      = gcMemoryStringBuilder.ToString();
                    profilersString     = profilersStringBuilder.ToString();
                    fpsStatString       = fpsStatStringBuilder.ToString();
                }
            });
            stringBuilderTask.Start();
        }
예제 #2
0
        private void UpdateProfilingStrings()
        {
            profilersStringBuilder.Clear();
            fpsStatStringBuilder.Clear();
            gpuInfoStringBuilder.Clear();
            gpuGeneralInfoStringBuilder.Clear();

            //Advance any profiler that needs it
            gcProfiler.Tick();

            // calculate elaspsed frames
            var newDraw       = Game.DrawTime.FrameCount;
            var elapsedFrames = newDraw - lastFrame;

            lastFrame = newDraw;

            // Get events from the profiler ( this will also clean up the profiler )
            var events = Profiler.GetEvents(FilteringMode == GameProfilingResults.CpuEvents? ProfilingEventType.CpuProfilingEvent : ProfilingEventType.GpuProfilingEvent);

            if (FilteringMode != GameProfilingResults.Fps)
            {
                var containsMarks = false;
                var tickFrequency = FilteringMode == GameProfilingResults.GpuEvents ? GraphicsDevice.TimestampFrequency : Stopwatch.Frequency;

                const float kb = 1 << 10;
                const float mb = 1 << 20;
                //update strings that need update
                foreach (var e in events)
                {
                    //gc profiling is a special case
                    if (e.Key == GcProfiling.GcMemoryKey && e.Custom0.HasValue && e.Custom1.HasValue && e.Custom2.HasValue)
                    {
                        gcMemoryStringBuilder.Clear();
                        gcMemoryStringBuilder.AppendFormat(gcMemoryStringBase, e.Custom0.Value.LongValue / mb, e.Custom2.Value.LongValue / mb, e.Custom1.Value.LongValue / kb);
                        continue;
                    }

                    if (e.Key == GcProfiling.GcCollectionCountKey && e.Custom0.HasValue && e.Custom1.HasValue && e.Custom2.HasValue)
                    {
                        gcCollectionsStringBuilder.Clear();
                        gcCollectionsStringBuilder.AppendFormat(gcCollectionsStringBase, e.Custom0.Value.IntValue, e.Custom1.Value.IntValue, e.Custom2.Value.IntValue);
                        continue;
                    }

                    if (e.Key == GameProfilingKeys.GameDrawFPS && e.Type == ProfilingMessageType.End)
                    {
                        continue;
                    }

                    ProfilingResult profilingResult;
                    if (!profilingResultsDictionary.TryGetValue(e.Key, out profilingResult))
                    {
                        profilingResult.MinTime = long.MaxValue;
                    }


                    if (e.Type == ProfilingMessageType.End)
                    {
                        ++profilingResult.Count;
                        profilingResult.AccumulatedTime += e.ElapsedTime;

                        if (e.ElapsedTime < profilingResult.MinTime)
                        {
                            profilingResult.MinTime = e.ElapsedTime;
                        }
                        if (e.ElapsedTime > profilingResult.MaxTime)
                        {
                            profilingResult.MaxTime = e.ElapsedTime;
                        }

                        profilingResult.Event = e;
                    }
                    else if (e.Type == ProfilingMessageType.Mark)
                    {
                        profilingResult.MarkCount++;
                        containsMarks = true;
                    }

                    if (e.Custom0.HasValue)
                    {
                        profilingResult.Custom0 = e.Custom0.Value;
                    }
                    if (e.Custom1.HasValue)
                    {
                        profilingResult.Custom1 = e.Custom1.Value;
                    }
                    if (e.Custom2.HasValue)
                    {
                        profilingResult.Custom2 = e.Custom2.Value;
                    }
                    if (e.Custom3.HasValue)
                    {
                        profilingResult.Custom3 = e.Custom3.Value;
                    }

                    profilingResultsDictionary[e.Key] = profilingResult;
                }

                profilersStringBuilder.Clear();
                profilingResults.Clear();

                foreach (var profilingResult in profilingResultsDictionary)
                {
                    if (!profilingResult.Value.Event.HasValue)
                    {
                        continue;
                    }
                    profilingResults.Add(profilingResult.Value);
                }
                profilingResultsDictionary.Clear();

                if (SortingMode == GameProfilingSorting.ByTime)
                {
                    profilingResults.Sort((x1, x2) => Math.Sign(x2.AccumulatedTime - x1.AccumulatedTime));
                }
                else
                {
                    // Can't be null because we skip those events without values
                    // ReSharper disable PossibleInvalidOperationException
                    profilingResults.Sort((x1, x2) => string.Compare(x1.Event.Value.Key.Name, x2.Event.Value.Key.Name, StringComparison.Ordinal));
                    // ReSharper restore PossibleInvalidOperationException
                }

                var availableDisplayHeight = viewportHeight - 2 * TextRowHeight - 3 * TopRowHeight;
                var elementsPerPage        = (int)Math.Floor(availableDisplayHeight / TextRowHeight);
                numberOfPages     = (uint)Math.Ceiling(profilingResults.Count / (float)elementsPerPage);
                CurrentResultPage = Math.Min(CurrentResultPage, numberOfPages);

                profilersStringBuilder.AppendFormat("TOTAL     | AVG/CALL  | MIN/CALL  | MAX/CALL  | CALLS | ");
                if (containsMarks)
                {
                    profilersStringBuilder.AppendFormat("MARKS | ");
                }
                profilersStringBuilder.AppendFormat("PROFILING KEY / EXTRA INFO\n");

                for (int i = 0; i < Math.Min(profilingResults.Count - (CurrentResultPage - 1) * elementsPerPage, elementsPerPage); i++)
                {
                    AppendEvent(profilingResults[((int)CurrentResultPage - 1) * elementsPerPage + i], elapsedFrames, tickFrequency, containsMarks);
                }
                profilingResults.Clear();

                if (numberOfPages > 1)
                {
                    profilersStringBuilder.AppendFormat("PAGE {0} OF {1}", CurrentResultPage, numberOfPages);
                }

                gpuInfoStringBuilder.Clear();
                gpuInfoStringBuilder.AppendFormat("Drawn triangles: {0:0.0}k, Draw calls: {1}, Buffer memory: {2:0.00}[MB], Texture memory: {3:0.00}[MB]", trianglesCount / 1000f, drawCallsCount, GraphicsDevice.BuffersMemory / mb, GraphicsDevice.TextureMemory / mb);

                gpuGeneralInfoStringBuilder.Clear();
                gpuGeneralInfoStringBuilder.AppendFormat("Device: {0}, Platform: {1}, Profile: {2}, Resolution: {3}", GraphicsDevice.Adapter.Description, GraphicsDevice.Platform, GraphicsDevice.ShaderProfile, renderTargetSize);
            }

            fpsStatStringBuilder.Clear();
            fpsStatStringBuilder.AppendFormat("Displaying: {0}, Frame: {1}, Update: {2:0.00}ms, Draw: {3:0.00}ms, FPS: {4:0.00}", FilteringMode, Game.DrawTime.FrameCount, Game.UpdateTime.TimePerFrame.TotalMilliseconds, Game.DrawTime.TimePerFrame.TotalMilliseconds, Game.DrawTime.FramePerSecond);

            lock (stringLock)
            {
                gcCollectionsString  = gcCollectionsStringBuilder.ToString();
                gcMemoryString       = gcMemoryStringBuilder.ToString();
                profilersString      = profilersStringBuilder.ToString();
                fpsStatString        = fpsStatStringBuilder.ToString();
                gpuInfoString        = gpuInfoStringBuilder.ToString();
                gpuGeneralInfoString = gpuGeneralInfoStringBuilder.ToString();
            }
        }