using System; using System.Diagnostics; using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Unity.Collections.LowLevel.Unsafe; using Unity.Profiling.LowLevel; using Unity.Profiling.LowLevel.Unsafe; namespace Unity.Profiling { /// /// Reports a value of an integer or floating point type to the Unity Profiler. /// /// int, uint, long, ulong, float or double type. #if ENABLE_PROFILER [StructLayout(LayoutKind.Sequential)] #else [StructLayout(LayoutKind.Sequential, Size = 0)] #endif public readonly struct ProfilerCounter where T : unmanaged { #if ENABLE_PROFILER [NativeDisableUnsafePtrRestriction] [NonSerialized] readonly IntPtr m_Ptr; [NonSerialized] readonly byte m_Type; #endif /// /// Constructs a **ProfilerCounter** that is reported to the Unity Profiler whenever you call Sample(). /// /// Profiler category. /// Name of ProfilerCounter. /// Value unit type. [MethodImpl(MethodImplOptions.AggressiveInlining)] public ProfilerCounter(ProfilerCategory category, string name, ProfilerMarkerDataUnit dataUnit) { #if ENABLE_PROFILER m_Type = ProfilerUtility.GetProfilerMarkerDataType(); m_Ptr = ProfilerUnsafeUtility.CreateMarker(name, category, MarkerFlags.Counter, 1); ProfilerUnsafeUtility.SetMarkerMetadata(m_Ptr, 0, null, m_Type, (byte)dataUnit); #endif } /// /// Sends the value to Unity Profiler immediately. /// /// Does nothing in Release Players. /// The value to send to the profiler. [MethodImpl(MethodImplOptions.AggressiveInlining)] [Conditional("ENABLE_PROFILER")] [Pure] public void Sample(T value) { #if ENABLE_PROFILER unsafe { var data = new ProfilerMarkerData { Type = m_Type, Size = (uint)UnsafeUtility.SizeOf(), Ptr = UnsafeUtility.AddressOf(ref value) }; ProfilerUnsafeUtility.SingleSampleWithMetadata(m_Ptr, 1, &data); } #endif } } }