ProfilerServiceImpl.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. namespace SRDebugger.Profiler
  2. {
  3. using System.Diagnostics;
  4. using Services;
  5. using SRF;
  6. using SRF.Service;
  7. using UnityEngine;
  8. public class ProfilerServiceImpl : SRServiceBase<IProfilerService>, IProfilerService
  9. {
  10. public float AverageFrameTime { get; private set; }
  11. public float LastFrameTime { get; private set; }
  12. public CircularBuffer<ProfilerFrame> FrameBuffer
  13. {
  14. get { return _frameBuffer; }
  15. }
  16. private const int FrameBufferSize = 400;
  17. private readonly CircularBuffer<ProfilerFrame>
  18. _frameBuffer = new CircularBuffer<ProfilerFrame>(FrameBufferSize);
  19. private ProfilerLateUpdateListener _lateUpdateListener;
  20. private readonly Stopwatch _stopwatch = new Stopwatch();
  21. // Time between first Update() and last LateUpdate().
  22. private double _updateDuration;
  23. // Time that first camera rendered.
  24. private double _renderStartTime;
  25. // Time between first camera prerender and last camera postrender.
  26. private double _renderDuration;
  27. private int _camerasThisFrame;
  28. protected override void Awake()
  29. {
  30. base.Awake();
  31. _lateUpdateListener = gameObject.AddComponent<ProfilerLateUpdateListener>();
  32. _lateUpdateListener.OnLateUpdate = OnLateUpdate;
  33. CachedGameObject.hideFlags = HideFlags.NotEditable;
  34. CachedTransform.SetParent(Hierarchy.Get("SRDebugger"), true);
  35. Camera.onPreRender += OnCameraPreRender;
  36. Camera.onPostRender += OnCameraPostRender;
  37. }
  38. protected override void Update()
  39. {
  40. base.Update();
  41. _camerasThisFrame = 0;
  42. EndFrame();
  43. // Set the frame time for the last frame
  44. if (FrameBuffer.Count > 0)
  45. {
  46. var frame = FrameBuffer.Back();
  47. frame.FrameTime = Time.unscaledDeltaTime;
  48. FrameBuffer[FrameBuffer.Count - 1] = frame;
  49. }
  50. LastFrameTime = Time.unscaledDeltaTime;
  51. var frameCount = Mathf.Min(20, FrameBuffer.Count);
  52. var f = 0d;
  53. for (var i = 0; i < frameCount; i++)
  54. {
  55. f += FrameBuffer[FrameBuffer.Count - 1 - i].FrameTime;
  56. }
  57. AverageFrameTime = (float) f / frameCount;
  58. _stopwatch.Start();
  59. }
  60. protected void PushFrame(double totalTime, double updateTime, double renderTime)
  61. {
  62. //UnityEngine.Debug.Log("Frame: u: {0} r: {1}".Fmt(updateTime, renderTime));
  63. _frameBuffer.PushBack(new ProfilerFrame
  64. {
  65. OtherTime = totalTime - updateTime - renderTime,
  66. UpdateTime = updateTime,
  67. RenderTime = renderTime
  68. });
  69. }
  70. private void OnLateUpdate()
  71. {
  72. _updateDuration = _stopwatch.Elapsed.TotalSeconds;
  73. }
  74. private void OnCameraPreRender(Camera cam)
  75. {
  76. if (_camerasThisFrame == 0)
  77. {
  78. _renderStartTime = _stopwatch.Elapsed.TotalSeconds;
  79. }
  80. _camerasThisFrame++;
  81. }
  82. private void OnCameraPostRender(Camera cam)
  83. {
  84. _renderDuration = _stopwatch.Elapsed.TotalSeconds - _renderStartTime;
  85. }
  86. private void EndFrame()
  87. {
  88. if (_stopwatch.IsRunning)
  89. {
  90. PushFrame(_stopwatch.Elapsed.TotalSeconds, _updateDuration, _renderDuration);
  91. _stopwatch.Reset();
  92. _stopwatch.Start();
  93. }
  94. _updateDuration = _renderDuration = 0;
  95. }
  96. }
  97. }