129 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C#
		
	
	
	
		
		
			
		
	
	
			129 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C#
		
	
	
	
| 
								 | 
							
								namespace SRDebugger.Profiler
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    using System.Diagnostics;
							 | 
						|||
| 
								 | 
							
								    using Services;
							 | 
						|||
| 
								 | 
							
								    using SRF;
							 | 
						|||
| 
								 | 
							
								    using SRF.Service;
							 | 
						|||
| 
								 | 
							
								    using UnityEngine;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public class ProfilerServiceImpl : SRServiceBase<IProfilerService>, IProfilerService
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        public float AverageFrameTime { get; private set; }
							 | 
						|||
| 
								 | 
							
								        public float LastFrameTime { get; private set; }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        public CircularBuffer<ProfilerFrame> FrameBuffer
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            get { return _frameBuffer; }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        private const int FrameBufferSize = 400;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        private readonly CircularBuffer<ProfilerFrame>
							 | 
						|||
| 
								 | 
							
								            _frameBuffer = new CircularBuffer<ProfilerFrame>(FrameBufferSize);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        private ProfilerLateUpdateListener _lateUpdateListener;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        private readonly Stopwatch _stopwatch = new Stopwatch();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        // Time between first Update() and last LateUpdate().
							 | 
						|||
| 
								 | 
							
								        private double _updateDuration;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        // Time that first camera rendered.
							 | 
						|||
| 
								 | 
							
								        private double _renderStartTime;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        // Time between first camera prerender and last camera postrender.
							 | 
						|||
| 
								 | 
							
								        private double _renderDuration;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        private int _camerasThisFrame;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        protected override void Awake()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            base.Awake();
							 | 
						|||
| 
								 | 
							
								            _lateUpdateListener = gameObject.AddComponent<ProfilerLateUpdateListener>();
							 | 
						|||
| 
								 | 
							
								            _lateUpdateListener.OnLateUpdate = OnLateUpdate;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            CachedGameObject.hideFlags = HideFlags.NotEditable;
							 | 
						|||
| 
								 | 
							
								            CachedTransform.SetParent(Hierarchy.Get("SRDebugger"), true);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            Camera.onPreRender += OnCameraPreRender;
							 | 
						|||
| 
								 | 
							
								            Camera.onPostRender += OnCameraPostRender;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        protected override void Update()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            base.Update();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            _camerasThisFrame = 0;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            EndFrame();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            // Set the frame time for the last frame
							 | 
						|||
| 
								 | 
							
								            if (FrameBuffer.Count > 0)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                var frame = FrameBuffer.Back();
							 | 
						|||
| 
								 | 
							
								                frame.FrameTime = Time.unscaledDeltaTime;
							 | 
						|||
| 
								 | 
							
								                FrameBuffer[FrameBuffer.Count - 1] = frame;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            LastFrameTime = Time.unscaledDeltaTime;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            var frameCount = Mathf.Min(20, FrameBuffer.Count);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            var f = 0d;
							 | 
						|||
| 
								 | 
							
								            for (var i = 0; i < frameCount; i++)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                f += FrameBuffer[FrameBuffer.Count - 1 - i].FrameTime;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            AverageFrameTime = (float) f / frameCount;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            _stopwatch.Start();
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        protected void PushFrame(double totalTime, double updateTime, double renderTime)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            //UnityEngine.Debug.Log("Frame: u: {0} r: {1}".Fmt(updateTime, renderTime));
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            _frameBuffer.PushBack(new ProfilerFrame
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                OtherTime = totalTime - updateTime - renderTime,
							 | 
						|||
| 
								 | 
							
								                UpdateTime = updateTime,
							 | 
						|||
| 
								 | 
							
								                RenderTime = renderTime
							 | 
						|||
| 
								 | 
							
								            });
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        private void OnLateUpdate()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            _updateDuration = _stopwatch.Elapsed.TotalSeconds;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        private void OnCameraPreRender(Camera cam)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (_camerasThisFrame == 0)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                _renderStartTime = _stopwatch.Elapsed.TotalSeconds;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            _camerasThisFrame++;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        private void OnCameraPostRender(Camera cam)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            _renderDuration = _stopwatch.Elapsed.TotalSeconds - _renderStartTime;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        private void EndFrame()
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            if (_stopwatch.IsRunning)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                PushFrame(_stopwatch.Elapsed.TotalSeconds, _updateDuration, _renderDuration);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								                _stopwatch.Reset();
							 | 
						|||
| 
								 | 
							
								                _stopwatch.Start();
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            _updateDuration = _renderDuration = 0;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 |