using System; using System.Diagnostics; 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 integral 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 = 1)] #endif public readonly struct ProfilerCounterValue where T : unmanaged { #if ENABLE_PROFILER [NativeDisableUnsafePtrRestriction] [NonSerialized] readonly unsafe T* m_Value; #endif /// /// Constructs a **ProfilerCounter** that belongs to the generic ProfilerCategory.Scripts category. It is reported at the end of CPU frame to the Unity Profiler. /// /// Name of ProfilerCounter. [MethodImpl(MethodImplOptions.AggressiveInlining)] public ProfilerCounterValue(string name) { #if ENABLE_PROFILER byte dataType = ProfilerUtility.GetProfilerMarkerDataType(); unsafe { m_Value = (T*)ProfilerUnsafeUtility.CreateCounterValue(out var counterPtr, name, ProfilerUnsafeUtility.CategoryScripts, MarkerFlags.Default, dataType, (byte)ProfilerMarkerDataUnit.Undefined, UnsafeUtility.SizeOf(), ProfilerCounterOptions.FlushOnEndOfFrame); } #endif } /// /// Constructs a **ProfilerCounter** that belongs to the generic ProfilerCategory.Scripts category. It is reported at the end of CPU frame to the Unity Profiler. /// /// Name of ProfilerCounter. /// Value unit type. [MethodImpl(MethodImplOptions.AggressiveInlining)] public ProfilerCounterValue(string name, ProfilerMarkerDataUnit dataUnit) { #if ENABLE_PROFILER byte dataType = ProfilerUtility.GetProfilerMarkerDataType(); unsafe { m_Value = (T*)ProfilerUnsafeUtility.CreateCounterValue(out var counterPtr, name, ProfilerUnsafeUtility.CategoryScripts, MarkerFlags.Default, dataType, (byte)dataUnit, UnsafeUtility.SizeOf(), ProfilerCounterOptions.FlushOnEndOfFrame); } #endif } /// /// Constructs a **ProfilerCounter** that belongs to generic ProfilerCategory.Scripts category. /// /// Name of ProfilerCounter. /// Value unit type. /// ProfilerCounter options. [MethodImpl(MethodImplOptions.AggressiveInlining)] public ProfilerCounterValue(string name, ProfilerMarkerDataUnit dataUnit, ProfilerCounterOptions counterOptions) { #if ENABLE_PROFILER byte dataType = ProfilerUtility.GetProfilerMarkerDataType(); unsafe { m_Value = (T*)ProfilerUnsafeUtility.CreateCounterValue(out var counterPtr, name, ProfilerUnsafeUtility.CategoryScripts, MarkerFlags.Default, dataType, (byte)dataUnit, UnsafeUtility.SizeOf(), counterOptions); } #endif } /// /// Constructs a **ProfilerCounter** that is reported at the end of CPU frame to the Unity Profiler. /// /// Profiler category. /// Name of ProfilerCounter. /// Value unit type. [MethodImpl(MethodImplOptions.AggressiveInlining)] public ProfilerCounterValue(ProfilerCategory category, string name, ProfilerMarkerDataUnit dataUnit) { #if ENABLE_PROFILER byte dataType = ProfilerUtility.GetProfilerMarkerDataType(); unsafe { m_Value = (T*)ProfilerUnsafeUtility.CreateCounterValue(out var counterPtr, name, category, MarkerFlags.Default, dataType, (byte)dataUnit, UnsafeUtility.SizeOf(), ProfilerCounterOptions.FlushOnEndOfFrame); } #endif } /// /// Constructs a **ProfilerCounter**. /// /// Profiler category. /// Name of ProfilerCounter. /// Value unit type. /// ProfilerCounter options. [MethodImpl(MethodImplOptions.AggressiveInlining)] public ProfilerCounterValue(ProfilerCategory category, string name, ProfilerMarkerDataUnit dataUnit, ProfilerCounterOptions counterOptions) { #if ENABLE_PROFILER byte dataType = ProfilerUtility.GetProfilerMarkerDataType(); unsafe { m_Value = (T*)ProfilerUnsafeUtility.CreateCounterValue(out var counterPtr, name, category, MarkerFlags.Default, dataType, (byte)dataUnit, UnsafeUtility.SizeOf(), counterOptions); } #endif } /// /// Gets or sets value of the ProfilerCounter. /// /// Returns 0 and is not implemented in Release Players. public T Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { #if ENABLE_PROFILER unsafe { return *m_Value; } #else return default; #endif } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { #if ENABLE_PROFILER unsafe { *m_Value = value; } #endif } } /// /// Sends the value to Unity Profiler immediately. /// [Conditional("ENABLE_PROFILER")] public void Sample() { #if ENABLE_PROFILER unsafe { ProfilerUnsafeUtility.FlushCounterValue(m_Value); } #endif } } }