You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CrowdControl/Assets/3rd/StompyRobot/SRDebugger/Scripts/Profiler/ProfilerServiceImpl.cs

129 lines
3.6 KiB
C#

1 month ago
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;
}
}
}