using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Threading; using Unity.Collections.LowLevel.Unsafe; namespace UnityEditor.Rendering { /// /// Allows time measurements /// /// /// double duration = 0; /// using (TimedScope.FromPtr(&duration)) /// { /// // something to get the time /// } /// Debug.Log($"Duration: {duration}") /// public unsafe struct TimedScope : IDisposable { static readonly ThreadLocal s_StopWatch = new ThreadLocal(() => new Stopwatch()); double* m_DurationMsPtr; TimedScope(double* durationMsPtr) { m_DurationMsPtr = durationMsPtr; s_StopWatch.Value.Start(); } /// /// Dispose method to retrieve the time /// void IDisposable.Dispose() { s_StopWatch.Value.Stop(); *m_DurationMsPtr = s_StopWatch.Value.Elapsed.TotalMilliseconds; s_StopWatch.Value.Reset(); } /// /// Obtains a . /// /// Safety: must be a non-null pointer to a valid memory location for a double. /// /// The location to write the duration in milliseconds to. /// A public static unsafe TimedScope FromPtr([DisallowNull] double* durationMsPtr) { return new TimedScope(durationMsPtr); } /// /// Obtains a /// /// The location to write the duration in milliseconds to. /// A public static TimedScope FromRef(ref double durationMs) { return new TimedScope((double*)UnsafeUtility.AddressOf(ref durationMs)); } } }