public HistoryLock(MyProfiler profiler, FastResourceLock historyLock) { m_profiler = profiler; m_lock = historyLock; m_lock.AcquireExclusive(); m_profiler.OnHistorySafe(); }
internal void DestroyThread() { m_threadProfilers.Remove(m_threadProfiler); if (m_selectedProfiler == m_threadProfiler) { m_selectedProfiler = m_threadProfilers.Count > 0 ? m_threadProfilers[0] : null; } m_threadProfiler = null; }
/// <summary> /// Creates new profiler which can be used to profile anything (e.g. network stats). /// </summary> public static MyProfiler CreateProfiler(string name, string axisName = null, bool memoryProfiling = false) { lock (m_threadProfilers) { var profiler = new MyProfiler(memoryProfiling, name, axisName ?? "[ms]"); m_threadProfilers.Add(profiler); profiler.SetNewLevelLimit(m_profilerProcessingEnabled ? m_levelLimit : 0); if (m_selectedProfiler == null) { m_selectedProfiler = profiler; } return(profiler); } }
static NetProfiler() { m_profiler = MyRenderProfiler.CreateProfiler("Network", "B"); m_profiler.AutoCommit = false; }
protected override void Draw(VRage.Profiler.MyProfiler drawProfiler, int lastFrameIndex, int frameToDraw) { }
protected abstract void Draw(MyProfiler drawProfiler, int lastFrameIndex, int frameToDraw);
/// <summary> /// Creates new profiler which can be used to profile anything (e.g. network stats). /// </summary> public static MyProfiler CreateProfiler(string name, string axisName = null, bool memoryProfiling = false) { lock (m_threadProfilers) { var profiler = new MyProfiler(memoryProfiling, name, axisName ?? "[ms]"); m_threadProfilers.Add(profiler); profiler.SetNewLevelLimit(m_profilerProcessingEnabled ? m_levelLimit : 0); if (m_selectedProfiler == null) m_selectedProfiler = profiler; return profiler; } }
static MyRenderProfiler() { m_levelLimit = VRage.MyCompilationSymbols.ProfileFromStart ? -1 : 0; // Create block, some unique id m_fpsBlock = MyProfiler.CreateExternalBlock("FPS", -2); }
public void DrawEvent(float textPosY, MyProfiler.MyProfilerBlock profilerBlock, int blockIndex, int frameIndex, int lastValidFrame) { Color color = IndexToColor(blockIndex); float miliseconds = 0; float managedMemory = 0; float processMemory = 0; int numCalls = -1; // To show update window in profiler float customValue = 0; if (IsValidIndex(frameIndex, lastValidFrame)) { miliseconds = profilerBlock.Miliseconds[frameIndex]; managedMemory = profilerBlock.ManagedMemory[frameIndex]; processMemory = profilerBlock.ProcessMemory[frameIndex]; numCalls = profilerBlock.NumCallsArray[frameIndex]; customValue = profilerBlock.CustomValues[frameIndex]; } float Y_TEXT_POSITION = MyRender.GraphicsDevice.Viewport.Height / 2; float textScale = 0.7f; m_text.Clear().Append(blockIndex + 1).Append(" ").Append(profilerBlock.Name); MyRender.DrawTextShadow(new Vector2(20, textPosY), m_text, color, textScale); float length = 500; m_text.Clear(); m_text.Append("(").Append(profilerBlock.Children.Count).Append(") "); MyRender.DrawTextShadow(new Vector2(20 + length, textPosY), m_text, color, textScale); length += 50 * textScale; m_text.Clear(); //text.Append(((index != -1 ? profilerBlock.TimePercentage[index] : profilerBlock.averagePctg)).ToString("#,#0.0%")); //MyDebugDraw.DrawTextShadow(new Vector2(20 + length, textPosY), text, color, textScale); length += 155 * textScale; m_text.Clear(); m_text.ConcatFormat(profilerBlock.TimeFormat ?? "{0:.00}ms", miliseconds); MyRender.DrawTextShadow(new Vector2(20 + length, textPosY), m_text, color, textScale); length += 155 * textScale; m_text.Clear(); m_text.Concat(managedMemory, 3).Append(" GC"); MyRender.DrawTextShadow(new Vector2(20 + length, textPosY), m_text, color, textScale); length += 40 + 158 * textScale; m_text.Clear(); if (MemoryProfiling) { m_text.Concat(processMemory, 3).Append(" MB"); MyRender.DrawTextShadow(new Vector2(20 + length, textPosY), m_text, color, textScale); length += 158 * textScale; m_text.Clear(); } length += 40 + 40 * textScale; m_text.Append(numCalls); m_text.Append(" calls"); MyRender.DrawTextShadow(new Vector2(20 + length, textPosY), m_text, color, textScale); length += 150 * textScale; m_text.Clear(); m_text.ConcatFormat(profilerBlock.ValueFormat ?? "Custom: {0:.00}", customValue); MyRender.DrawTextShadow(new Vector2(20 + length, textPosY), m_text, color, textScale); int maxIndex; length += 250 * textScale; float max = FindMaxWrap(profilerBlock.Miliseconds, frameIndex - m_frameLocalArea / 2, frameIndex + m_frameLocalArea / 2, lastValidFrame, out maxIndex); m_text.Clear(); m_text.ConcatFormat(profilerBlock.TimeFormat ?? "{0:.00}ms", max); MyRender.DrawTextShadow(new Vector2(20 + length, textPosY), m_text, color, textScale); length += MyRender.DrawTextShadow(new Vector2(20 + length, textPosY), m_text, color, textScale); }
protected override void Draw(MyProfiler drawProfiler, int lastFrameIndex, int frameToDraw) { Debug.Assert(frameToDraw >= 0 && frameToDraw < MyProfiler.MAX_FRAMES, "Invalid selected frame"); // Init linebatch if (m_lineBatch == null) { SharpDX.Direct3D9.Device device = MyRender.GraphicsDevice; m_lineBatch = new MyLineBatch(Matrix.Identity, Matrix.CreateOrthographicOffCenter(0, device.Viewport.Width, device.Viewport.Height, 0, 0, -1), 50000); m_fpsBlock.Start(false); } // Handle FPS timer m_fpsBlock.End(false); float elapsedTime = (float)m_fpsBlock.Elapsed.Seconds; float invElapsedTime = elapsedTime > 0 ? 1 / elapsedTime : 0; m_fpsPctg = 0.9f * m_fpsPctg + 0.1f * invElapsedTime; if (MemoryProfiling) { // Handle memory usage for frame float processDeltaMB = m_fpsBlock.ProcessDeltaMB; m_fpsBlock.ProcessMemory[lastFrameIndex] = processDeltaMB; } float managedDeltaMB = m_fpsBlock.ManagedDeltaMB; m_fpsBlock.ManagedMemory[lastFrameIndex] = managedDeltaMB; m_fpsBlock.CustomValues[lastFrameIndex] = m_fpsBlock.CustomValue; m_fpsBlock.Reset(); m_fpsBlock.Start(false); if (m_enabled) { // Draw events as text float eventLineSize = 20; float largeTextLineSize = 28; float textOffsetY = MyRender.GraphicsDevice.Viewport.Height / 2 - 8 * largeTextLineSize; // Draw thread name and level limit m_text.Clear(); m_text.ConcatFormat("\"{2}\" ({0}/{1})", m_selectedProfiler.GlobalProfilerIndex + 1, m_threadProfilers.Count, m_selectedProfiler.OwnerThread.Name).AppendLine(); m_text.Append("Level limit: ").AppendInt32(m_levelLimit).AppendLine(); MyRender.DrawText(new Vector2(20, textOffsetY), m_text, Color.LightGray, 1); textOffsetY += largeTextLineSize * 2 + 10; // Draw frame number and local area m_text.Clear(); m_text.Append("Frame: ").AppendInt32(frameToDraw).AppendLine(); m_text.Append("Local area: ").AppendInt32(m_frameLocalArea); MyRender.DrawText(new Vector2(20, textOffsetY), m_text, Color.Yellow, 1); textOffsetY += largeTextLineSize * 2 + 10; // Draw fps and total calls m_text.Clear(); m_text.Append(m_fpsBlock.Name).Append(" "); if (!m_useCustomFrame) // Show FPS only when not using custom frame m_text.AppendDecimal(m_fpsPctg, 3); m_text.AppendLine(); m_text.Append("Total calls: ").AppendInt32(IsValidIndex(frameToDraw, lastFrameIndex) ? m_selectedProfiler.TotalCalls[frameToDraw] : -1); MyRender.DrawText(new Vector2(20, textOffsetY), m_text, Color.Red, 1); textOffsetY += largeTextLineSize; textOffsetY = MyRender.GraphicsDevice.Viewport.Height / 2; var children = m_selectedProfiler.SelectedRootChildren; for (int i = 0; i < children.Count; i++) { MyProfiler.MyProfilerBlock profilerBlock = children[i]; DrawEvent(textOffsetY, profilerBlock, i, frameToDraw, lastFrameIndex); textOffsetY += eventLineSize; } // Draw graphs m_lineBatch.Begin(); DrawPerfEvents(lastFrameIndex); VRageRender.Graphics.BlendState.Opaque.Apply(); m_lineBatch.End(); } // Update horizontal offset if (!Paused && !m_useCustomFrame) { m_selectedFrame = lastFrameIndex; } }
public void StartProfilingBlock(string blockName = null, float customValue = 0, [CallerMemberName] string member = "", [CallerLineNumber] int line = 0, [CallerFilePath] string file = "") { ThreadProfiler.StartBlock(blockName, member, line, file); if (m_selectedProfiler == null) { m_selectedProfiler = ThreadProfiler; } }
public static void HandleInput(RenderProfilerCommand command, int index) { switch (command) { case RenderProfilerCommand.Enable: { // Enable or Disable profiler drawing if (m_enabled && m_selectedProfiler.SelectedRoot == null) { m_enabled = false; m_useCustomFrame = false; } else if (!m_enabled) { m_enabled = true; } else { // Go to parent node if (m_selectedProfiler.SelectedRoot != null) { m_selectedProfiler.SelectedRoot = m_selectedProfiler.SelectedRoot.Parent; } } break; } case RenderProfilerCommand.JumpToLevel: { m_selectedProfiler.SelectedRoot = FindBlockByIndex(index - 1); // On screen it's indexed from 1 (zero is level up) break; } case RenderProfilerCommand.FindMaxChild: { MyProfiler.MyProfilerBlock block; int lastFrameIndex; using (m_selectedProfiler.LockHistory(out lastFrameIndex)) { block = FindBlockByMax(m_selectedFrame, lastFrameIndex); } if (block != null) { m_selectedProfiler.SelectedRoot = block; } break; } case RenderProfilerCommand.Pause: { Paused = !Paused; m_useCustomFrame = false; // Turn-off custom frame after ALT + ENTER break; } case RenderProfilerCommand.NextThread: { lock (m_threadProfilers) { int profilerIndex = (m_threadProfilers.IndexOf(m_selectedProfiler) + 1) % m_threadProfilers.Count; m_selectedProfiler = m_threadProfilers[profilerIndex]; } break; } case RenderProfilerCommand.PreviousThread: { lock (m_threadProfilers) { int profilerIndex = (m_threadProfilers.IndexOf(m_selectedProfiler) - 1 + m_threadProfilers.Count) % m_threadProfilers.Count; m_selectedProfiler = m_threadProfilers[profilerIndex]; } break; } case RenderProfilerCommand.NextFrame: { MyRenderProfiler.NextFrame(); break; } case RenderProfilerCommand.PreviousFrame: { MyRenderProfiler.PreviousFrame(); break; } case RenderProfilerCommand.IncreaseLevel: { m_levelLimit++; SetLevel(); break; } case RenderProfilerCommand.DecreaseLevel: { m_levelLimit--; if (m_levelLimit < -1) m_levelLimit = -1; SetLevel(); break; } case RenderProfilerCommand.DecreaseLocalArea: m_frameLocalArea = Math.Max(2, m_frameLocalArea / 2); break; case RenderProfilerCommand.IncreaseLocalArea: m_frameLocalArea = Math.Min(MyProfiler.MAX_FRAMES, m_frameLocalArea * 2); break; case RenderProfilerCommand.IncreaseRange: m_milisecondsGraphScale.IncreaseYRange(); break; case RenderProfilerCommand.DecreaseRange: m_milisecondsGraphScale.DecreaseYRange(); break; default: System.Diagnostics.Debug.Assert(false, "Unknown command"); break; } }
void DrawEvent(float textPosY, MyProfiler.MyProfilerBlock profilerBlock, int blockIndex, int frameIndex, int lastValidFrame, ref Color color) { float miliseconds = 0; long managedMemory = 0; float processMemory = 0; int numCalls = -1; // To show update window in profiler float customValue = 0; if (IsValidIndex(frameIndex, lastValidFrame)) { miliseconds = profilerBlock.Miliseconds[frameIndex]; managedMemory = profilerBlock.ManagedMemoryBytes[frameIndex]; processMemory = profilerBlock.ProcessMemory[frameIndex]; numCalls = profilerBlock.NumCallsArray[frameIndex]; customValue = profilerBlock.CustomValues[frameIndex]; } float Y_TEXT_POSITION = ViewportSize.Y / 2; float textScale = 0.7f; m_text.Clear().Append(blockIndex + 1).Append(" ").Append(profilerBlock.Name); DrawTextShadow(new Vector2(20, textPosY), m_text, color, textScale); float length = 500; m_text.Clear(); m_text.Append("(").Append(profilerBlock.Children.Count).Append(") "); DrawTextShadow(new Vector2(20 + length, textPosY), m_text, color, textScale); length += 50 * textScale; m_text.Clear(); //text.Append(((index != -1 ? profilerBlock.TimePercentage[index] : profilerBlock.averagePctg)).ToString("#,#0.0%")); //MyDebugDraw.DrawTextShadow(new Vector2(20 + length, textPosY), text, color, textScale); length += 155 * textScale; m_text.Clear(); m_text.ConcatFormat(profilerBlock.TimeFormat ?? "{0:.00}ms", miliseconds); DrawTextShadow(new Vector2(20 + length, textPosY), m_text, color, textScale); length += 155 * textScale; m_text.Clear(); if (managedMemory < 1024 && managedMemory > -1024) // Still in bytes? { m_text.Append(managedMemory.ToString()).Append(" B"); } else if (managedMemory < 1048576 && managedMemory > -1048576) // Still in kilobytes? { float managedMemoryKB = managedMemory / 1024f; m_text.Concat(managedMemoryKB, 3).Append(" KB"); } else // Else display in megabytes { float managedMemoryKB = managedMemory / 1048576; m_text.Concat(managedMemoryKB, 3).Append(" MB"); } DrawTextShadow(new Vector2(20 + length, textPosY), m_text, color, textScale); length += 40 + 158 * textScale; m_text.Clear(); if (MemoryProfiling) { m_text.Concat(processMemory, 3).Append(" MB"); DrawTextShadow(new Vector2(20 + length, textPosY), m_text, color, textScale); length += 158 * textScale; m_text.Clear(); } length += 40 + 40 * textScale; m_text.ConcatFormat(profilerBlock.CallFormat ?? "{0} calls", numCalls); DrawTextShadow(new Vector2(20 + length, textPosY), m_text, color, textScale); length += 150 * textScale; m_text.Clear(); m_text.ConcatFormat(profilerBlock.ValueFormat ?? "Custom: {0:.00}", customValue); DrawTextShadow(new Vector2(20 + length, textPosY), m_text, color, textScale); int maxIndex; length += 250 * textScale; float max = FindMaxWrap(profilerBlock.Miliseconds, frameIndex - m_frameLocalArea / 2, frameIndex + m_frameLocalArea / 2, lastValidFrame, out maxIndex); m_text.Clear(); m_text.ConcatFormat(profilerBlock.TimeFormat ?? "{0:.00}ms", max); DrawTextShadow(new Vector2(20 + length, textPosY), m_text, color, textScale); length += DrawTextShadow(new Vector2(20 + length, textPosY), m_text, color, textScale); }
protected sealed override void Draw(MyProfiler drawProfiler, int lastFrameIndex, int frameToDraw) { Debug.Assert(frameToDraw >= 0 && frameToDraw < MyProfiler.MAX_FRAMES, "Invalid selected frame"); if (!m_initialized) { // Init linebatch Init(); m_initialized = true; m_fpsBlock.Start(false); } // Handle FPS timer m_fpsBlock.End(false); float elapsedTime = (float)m_fpsBlock.Elapsed.Seconds; float invElapsedTime = elapsedTime > 0 ? 1 / elapsedTime : 0; m_fpsPctg = 0.9f * m_fpsPctg + 0.1f * invElapsedTime; if (MemoryProfiling) { // Handle memory usage for frame float processDeltaMB = m_fpsBlock.ProcessDeltaMB; m_fpsBlock.ProcessMemory[lastFrameIndex] = processDeltaMB; } long managedDeltaMB = m_fpsBlock.ManagedDeltaMB; m_fpsBlock.ManagedMemoryBytes[lastFrameIndex] = managedDeltaMB; m_fpsBlock.CustomValues[lastFrameIndex] = m_fpsBlock.CustomValue; m_fpsBlock.Reset(); m_fpsBlock.Start(false); if (m_enabled) { // Draw events as text float eventLineSize = 20; float largeTextLineSize = 28; float textOffsetY = ViewportSize.Y / 2 - 8 * largeTextLineSize; // Draw thread name and level limit m_text.Clear(); m_text.ConcatFormat("\"{2}\" ({0}/{1})", m_threadProfilers.IndexOf(m_selectedProfiler) + 1, m_threadProfilers.Count, m_selectedProfiler.DisplayedName).AppendLine(); m_text.Append("Level limit: ").AppendInt32(m_selectedProfiler.LevelLimit).AppendLine(); DrawText(new Vector2(20, textOffsetY), m_text, Color.LightGray, 1); textOffsetY += largeTextLineSize * 2 + 10; // Draw frame number and local area m_text.Clear(); m_text.Append("Frame: ").AppendInt32(frameToDraw).AppendLine(); m_text.Append("Local area: ").AppendInt32(m_frameLocalArea); DrawText(new Vector2(20, textOffsetY), m_text, Color.Yellow, 1); textOffsetY += largeTextLineSize * 2 + 10; // Draw fps and total calls m_text.Clear(); m_text.Append(m_fpsBlock.Name).Append(" "); if (!m_useCustomFrame) // Show FPS only when not using custom frame m_text.AppendDecimal(m_fpsPctg, 3); m_text.AppendLine(); m_text.Append("Total calls: ").AppendInt32(IsValidIndex(frameToDraw, lastFrameIndex) ? m_selectedProfiler.TotalCalls[frameToDraw] : -1); DrawText(new Vector2(20, textOffsetY), m_text, Color.Red, 1); textOffsetY += largeTextLineSize; m_text.Clear(); if (!VRage.MyCompilationSymbols.PerformanceProfiling) { m_text.Append("MyCompilationSymbols.PerformanceProfiling NOT ENABLED!").AppendLine(); } if (!ProfilerProcessingEnabled) { m_text.Append("Profiler processing disabled, F12 -> Profiler").AppendLine(); } DrawText(new Vector2(0, 0), m_text, Color.Yellow, 0.6f); textOffsetY = ViewportSize.Y / 2; List<MyProfilerBlock> children = m_selectedProfiler.SelectedRootChildren; List<MyProfilerBlock> sortedChildren = GetSortedChildren(frameToDraw); // Draw the 'stack trace' m_text.Clear(); MyProfilerBlock currentBlock = m_selectedProfiler.SelectedRoot; while (currentBlock != null) { // Stop inserting new elements if the path becomes too long if (currentBlock.Name.Length + 3 + m_text.Length > 170) { m_text.Insert(0, "... > "); break; } if (m_text.Length > 0) m_text.Insert(0, " > "); m_text.Insert(0, currentBlock.Name); currentBlock = currentBlock.Parent; } DrawTextShadow(new Vector2(20, textOffsetY), m_text, Color.White, 0.7f); textOffsetY += eventLineSize; if (m_selectedProfiler.SelectedRoot != null) { Color whiteColor = Color.White; DrawEvent(textOffsetY, m_selectedProfiler.SelectedRoot, -1, frameToDraw, lastFrameIndex, ref whiteColor); textOffsetY += eventLineSize; } if (sortedChildren.Count > 0) { // Draw the sorting order indicator m_text.Clear().Append("\\/"); switch (m_sortingOrder) { case RenderProfilerSortingOrder.Id: m_text.Append(" ASC"); DrawTextShadow(new Vector2(20, textOffsetY), m_text, Color.White, 0.7f); break; case RenderProfilerSortingOrder.MillisecondsLastFrame: m_text.Append(" DESC"); DrawTextShadow(new Vector2(660, textOffsetY), m_text, Color.White, 0.7f); break; case RenderProfilerSortingOrder.MillisecondsAverage: m_text.Append(" DESC"); DrawTextShadow(new Vector2(1270, textOffsetY), m_text, Color.White, 0.7f); break; } textOffsetY += eventLineSize; // Draw the profiler blocks for (int i = 0; i < sortedChildren.Count; i++) { MyProfilerBlock profilerBlock = sortedChildren[i]; Color lineColor = IndexToColor(children.IndexOf(profilerBlock)); DrawEvent(textOffsetY, profilerBlock, i, frameToDraw, lastFrameIndex, ref lineColor); textOffsetY += eventLineSize; } } else { m_text.Clear().Append("No more blocks at this point!"); textOffsetY += eventLineSize; DrawTextShadow(new Vector2(20, textOffsetY), m_text, Color.White, 0.7f); textOffsetY += eventLineSize; } // Draw graphs BeginLineBatch(); DrawPerfEvents(lastFrameIndex); EndLineBatch(); } // Update horizontal offset if (!Paused && !m_useCustomFrame) { m_selectedFrame = lastFrameIndex; } }
public static void HandleInput(RenderProfilerCommand command, int index) { switch (command) { case RenderProfilerCommand.Enable: { if (!m_enabled) { m_enabled = true; m_profilerProcessingEnabled = true; // Enable when disabled and keep enabled SetLevel(); } break; } case RenderProfilerCommand.ToggleEnabled: { // Enable or Disable profiler drawing if (m_enabled) { m_enabled = false; m_useCustomFrame = false; } else { m_enabled = true; m_profilerProcessingEnabled = true; // Enable when disabled and keep enabled } break; } case RenderProfilerCommand.JumpToRoot: m_selectedProfiler.SelectedRoot = null; break; case RenderProfilerCommand.JumpToLevel: { // Enable when disabled, added this for programmers who are too used to using the numpad 0 to open the profiler. if (index == 0 && !m_enabled) { m_enabled = true; m_profilerProcessingEnabled = true; // Enable when disabled and keep enabled } else { m_selectedProfiler.SelectedRoot = FindBlockByIndex(index - 1); // On screen it's indexed from 1 (zero is level up) } break; } case RenderProfilerCommand.Pause: { Paused = !Paused; GpuProfiler.AutoCommit = !Paused; break; } case RenderProfilerCommand.NextThread: { lock (m_threadProfilers) { int profilerIndex = (m_threadProfilers.IndexOf(m_selectedProfiler) + 1) % m_threadProfilers.Count; m_selectedProfiler = m_threadProfilers[profilerIndex]; } break; } case RenderProfilerCommand.PreviousThread: { lock (m_threadProfilers) { int profilerIndex = (m_threadProfilers.IndexOf(m_selectedProfiler) - 1 + m_threadProfilers.Count) % m_threadProfilers.Count; m_selectedProfiler = m_threadProfilers[profilerIndex]; } break; } case RenderProfilerCommand.Reset: { lock (m_threadProfilers) { foreach (var profiler in m_threadProfilers) { profiler.Reset(); } m_selectedFrame = 0; } break; } case RenderProfilerCommand.NextFrame: { MyRenderProfiler.NextFrame(index); break; } case RenderProfilerCommand.PreviousFrame: { MyRenderProfiler.PreviousFrame(index); break; } case RenderProfilerCommand.DisableFrameSelection: { m_useCustomFrame = false; break; } case RenderProfilerCommand.IncreaseLevel: { m_levelLimit++; SetLevel(); break; } case RenderProfilerCommand.DecreaseLevel: { m_levelLimit--; if (m_levelLimit < -1) { m_levelLimit = -1; } SetLevel(); break; } case RenderProfilerCommand.CopyPathToClipboard: { StringBuilder pathBuilder = new StringBuilder(200); MyProfilerBlock currentBlock = m_selectedProfiler.SelectedRoot; while (currentBlock != null) { if (pathBuilder.Length > 0) { pathBuilder.Insert(0, " > "); } pathBuilder.Insert(0, currentBlock.Name); currentBlock = currentBlock.Parent; } if (pathBuilder.Length > 0) { // Clipboard can only be accessed from a thread on the STA apartment System.Threading.Thread thread = new System.Threading.Thread(() => System.Windows.Forms.Clipboard.SetText(pathBuilder.ToString())); thread.SetApartmentState(System.Threading.ApartmentState.STA); thread.Start(); thread.Join(); } break; } case RenderProfilerCommand.TryGoToPathInClipboard: { string fullPath = string.Empty; Exception threadEx = null; System.Threading.Thread staThread = new System.Threading.Thread( delegate() { try { fullPath = System.Windows.Forms.Clipboard.GetText(); } catch (Exception ex) { threadEx = ex; } }); staThread.SetApartmentState(System.Threading.ApartmentState.STA); staThread.Start(); staThread.Join(); if (!string.IsNullOrEmpty(fullPath)) { string[] split = fullPath.Split(new string[] { " > " }, StringSplitOptions.None); MyProfilerBlock pathBlock = null; List <MyProfilerBlock> blockSet = m_selectedProfiler.RootBlocks; for (int i = 0; i < split.Length; i++) { string blockName = split[i]; MyProfilerBlock oldPath = pathBlock; for (int j = 0; j < blockSet.Count; j++) { MyProfilerBlock block = blockSet[j]; if (block.Name == blockName) { pathBlock = block; blockSet = pathBlock.Children; break; } } // If the path did not change, we cannot go any deeper, break out of this loop if (oldPath == pathBlock) { break; } } if (pathBlock != null) { m_selectedProfiler.SelectedRoot = pathBlock; } } break; } case RenderProfilerCommand.SetLevel: { m_levelLimit = index; if (m_levelLimit < -1) { m_levelLimit = -1; } SetLevel(); break; } case RenderProfilerCommand.DecreaseLocalArea: m_frameLocalArea = Math.Max(2, m_frameLocalArea / 2); break; case RenderProfilerCommand.IncreaseLocalArea: m_frameLocalArea = Math.Min(MyProfiler.MAX_FRAMES, m_frameLocalArea * 2); break; case RenderProfilerCommand.IncreaseRange: m_milisecondsGraphScale.IncreaseYRange(); break; case RenderProfilerCommand.DecreaseRange: m_milisecondsGraphScale.DecreaseYRange(); break; case RenderProfilerCommand.ChangeSortingOrder: m_sortingOrder += 1; if (m_sortingOrder >= RenderProfilerSortingOrder.NumSortingTypes) { m_sortingOrder = RenderProfilerSortingOrder.Id; } break; default: System.Diagnostics.Debug.Assert(false, "Unknown command"); break; } }
public static void HandleInput(RenderProfilerCommand command, int index) { switch (command) { case RenderProfilerCommand.Enable: { if (!m_enabled) { m_enabled = true; m_profilerProcessingEnabled = true; // Enable when disabled and keep enabled SetLevel(); } break; } case RenderProfilerCommand.ToggleEnabled: { // Enable or Disable profiler drawing if (m_enabled) { m_enabled = false; m_useCustomFrame = false; } else { m_enabled = true; m_profilerProcessingEnabled = true; // Enable when disabled and keep enabled } break; } case RenderProfilerCommand.JumpToRoot: m_selectedProfiler.SelectedRoot = null; break; case RenderProfilerCommand.JumpToLevel: { // Enable when disabled, added this for programmers who are too used to using the numpad 0 to open the profiler. if (index == 0 && !m_enabled) { m_enabled = true; m_profilerProcessingEnabled = true; // Enable when disabled and keep enabled } else m_selectedProfiler.SelectedRoot = FindBlockByIndex(index - 1); // On screen it's indexed from 1 (zero is level up) break; } case RenderProfilerCommand.Pause: { Paused = !Paused; break; } case RenderProfilerCommand.NextThread: { lock (m_threadProfilers) { int profilerIndex = (m_threadProfilers.IndexOf(m_selectedProfiler) + 1) % m_threadProfilers.Count; m_selectedProfiler = m_threadProfilers[profilerIndex]; } break; } case RenderProfilerCommand.PreviousThread: { lock (m_threadProfilers) { int profilerIndex = (m_threadProfilers.IndexOf(m_selectedProfiler) - 1 + m_threadProfilers.Count) % m_threadProfilers.Count; m_selectedProfiler = m_threadProfilers[profilerIndex]; } break; } case RenderProfilerCommand.Reset: { lock (m_threadProfilers) { foreach (var profiler in m_threadProfilers) { profiler.Reset(); } m_selectedFrame = 0; } break; } case RenderProfilerCommand.NextFrame: { MyRenderProfiler.NextFrame(index); break; } case RenderProfilerCommand.PreviousFrame: { MyRenderProfiler.PreviousFrame(index); break; } case RenderProfilerCommand.DisableFrameSelection: { m_useCustomFrame = false; break; } case RenderProfilerCommand.IncreaseLevel: { m_levelLimit++; SetLevel(); break; } case RenderProfilerCommand.DecreaseLevel: { m_levelLimit--; if (m_levelLimit < -1) m_levelLimit = -1; SetLevel(); break; } case RenderProfilerCommand.CopyPathToClipboard: { StringBuilder pathBuilder = new StringBuilder(200); MyProfilerBlock currentBlock = m_selectedProfiler.SelectedRoot; while (currentBlock != null) { if (pathBuilder.Length > 0) pathBuilder.Insert(0, " > "); pathBuilder.Insert(0, currentBlock.Name); currentBlock = currentBlock.Parent; } if (pathBuilder.Length > 0) { // Clipboard can only be accessed from a thread on the STA apartment System.Threading.Thread thread = new System.Threading.Thread(() => System.Windows.Forms.Clipboard.SetText(pathBuilder.ToString())); thread.SetApartmentState(System.Threading.ApartmentState.STA); thread.Start(); thread.Join(); } break; } case RenderProfilerCommand.TryGoToPathInClipboard: { string fullPath = string.Empty; Exception threadEx = null; System.Threading.Thread staThread = new System.Threading.Thread( delegate() { try { fullPath = System.Windows.Forms.Clipboard.GetText(); } catch (Exception ex) { threadEx = ex; } }); staThread.SetApartmentState(System.Threading.ApartmentState.STA); staThread.Start(); staThread.Join(); if (!string.IsNullOrEmpty(fullPath)) { string[] split = fullPath.Split(new string[] { " > " }, StringSplitOptions.None); MyProfilerBlock pathBlock = null; List<MyProfilerBlock> blockSet = m_selectedProfiler.RootBlocks; for (int i = 0; i<split.Length; i++) { string blockName = split[i]; MyProfilerBlock oldPath = pathBlock; for (int j = 0; j<blockSet.Count; j++) { MyProfilerBlock block = blockSet[j]; if (block.Name == blockName) { pathBlock = block; blockSet = pathBlock.Children; break; } } // If the path did not change, we cannot go any deeper, break out of this loop if (oldPath == pathBlock) break; } if (pathBlock != null) m_selectedProfiler.SelectedRoot = pathBlock; } break; } case RenderProfilerCommand.SetLevel: { m_levelLimit = index; if (m_levelLimit < -1) m_levelLimit = -1; SetLevel(); break; } case RenderProfilerCommand.DecreaseLocalArea: m_frameLocalArea = Math.Max(2, m_frameLocalArea / 2); break; case RenderProfilerCommand.IncreaseLocalArea: m_frameLocalArea = Math.Min(MyProfiler.MAX_FRAMES, m_frameLocalArea * 2); break; case RenderProfilerCommand.IncreaseRange: m_milisecondsGraphScale.IncreaseYRange(); break; case RenderProfilerCommand.DecreaseRange: m_milisecondsGraphScale.DecreaseYRange(); break; case RenderProfilerCommand.ChangeSortingOrder: m_sortingOrder += 1; if (m_sortingOrder >= RenderProfilerSortingOrder.NumSortingTypes) m_sortingOrder = RenderProfilerSortingOrder.Id; break; default: System.Diagnostics.Debug.Assert(false, "Unknown command"); break; } }
internal void DestroyThread() { m_threadProfilers.Remove(m_threadProfiler); if (m_selectedProfiler == m_threadProfiler) m_selectedProfiler = m_threadProfilers.Count > 0 ? m_threadProfilers[0] : null; m_threadProfiler = null; }
protected sealed override void Draw(MyProfiler drawProfiler, int lastFrameIndex, int frameToDraw) { Debug.Assert(frameToDraw >= 0 && frameToDraw < MyProfiler.MAX_FRAMES, "Invalid selected frame"); if (!m_initialized) { // Init linebatch Init(); m_initialized = true; m_fpsBlock.Start(false); } // Handle FPS timer m_fpsBlock.End(false); float elapsedTime = (float)m_fpsBlock.Elapsed.Seconds; float invElapsedTime = elapsedTime > 0 ? 1 / elapsedTime : 0; m_fpsPctg = 0.9f * m_fpsPctg + 0.1f * invElapsedTime; if (MemoryProfiling) { // Handle memory usage for frame float processDeltaMB = m_fpsBlock.ProcessDeltaMB; m_fpsBlock.ProcessMemory[lastFrameIndex] = processDeltaMB; } float managedDeltaMB = m_fpsBlock.ManagedDeltaMB; m_fpsBlock.ManagedMemory[lastFrameIndex] = managedDeltaMB; m_fpsBlock.CustomValues[lastFrameIndex] = m_fpsBlock.CustomValue; m_fpsBlock.Reset(); m_fpsBlock.Start(false); if (m_enabled) { // Draw events as text float eventLineSize = 20; float largeTextLineSize = 28; float textOffsetY = ViewportSize.Y / 2 - 8 * largeTextLineSize; // Draw thread name and level limit m_text.Clear(); m_text.ConcatFormat("\"{2}\" ({0}/{1})", m_selectedProfiler.GlobalProfilerIndex + 1, m_threadProfilers.Count, m_selectedProfiler.DisplayedName).AppendLine(); m_text.Append("Level limit: ").AppendInt32(m_selectedProfiler.LevelLimit).AppendLine(); DrawText(new Vector2(20, textOffsetY), m_text, Color.LightGray, 1); textOffsetY += largeTextLineSize * 2 + 10; // Draw frame number and local area m_text.Clear(); m_text.Append("Frame: ").AppendInt32(frameToDraw).AppendLine(); m_text.Append("Local area: ").AppendInt32(m_frameLocalArea); DrawText(new Vector2(20, textOffsetY), m_text, Color.Yellow, 1); textOffsetY += largeTextLineSize * 2 + 10; // Draw fps and total calls m_text.Clear(); m_text.Append(m_fpsBlock.Name).Append(" "); if (!m_useCustomFrame) // Show FPS only when not using custom frame m_text.AppendDecimal(m_fpsPctg, 3); m_text.AppendLine(); m_text.Append("Total calls: ").AppendInt32(IsValidIndex(frameToDraw, lastFrameIndex) ? m_selectedProfiler.TotalCalls[frameToDraw] : -1); DrawText(new Vector2(20, textOffsetY), m_text, Color.Red, 1); textOffsetY += largeTextLineSize; m_text.Clear(); if (!VRage.MyCompilationSymbols.PerformanceProfiling) { m_text.Append("MyCompilationSymbols.PerformanceProfiling NOT ENABLED!").AppendLine(); } if (!ProfilerProcessingEnabled) { m_text.Append("Profiler processing disabled, F12 -> Profiler").AppendLine(); } DrawText(new Vector2(0, 0), m_text, Color.Yellow, 0.6f); textOffsetY = ViewportSize.Y / 2; var children = m_selectedProfiler.SelectedRootChildren; for (int i = 0; i < children.Count; i++) { MyProfiler.MyProfilerBlock profilerBlock = children[i]; DrawEvent(textOffsetY, profilerBlock, i, frameToDraw, lastFrameIndex); textOffsetY += eventLineSize; } // Draw graphs BeginLineBatch(); DrawPerfEvents(lastFrameIndex); EndLineBatch(); } // Update horizontal offset if (!Paused && !m_useCustomFrame) { m_selectedFrame = lastFrameIndex; } }