initial commit

This commit is contained in:
Jo 2025-01-07 02:06:59 +01:00
parent 6715289efe
commit 788c3389af
37645 changed files with 2526849 additions and 80 deletions

View file

@ -0,0 +1,89 @@
#if !UNITY_2020_2_OR_NEWER
using Unity.Profiling.LowLevel.Unsafe;
namespace Unity.Profiling
{
/// <summary>
/// Defines a profiling category when you create a ProfilerMarker.
/// </summary>
/// <seealso cref="ProfilerMarker{TP1}"/>
public struct ProfilerCategory
{
readonly ushort m_Category;
ProfilerCategory(ushort category)
{
m_Category = category;
}
/// <summary>
/// A ProfilerMarker that belongs to the Render system.
/// </summary>
public static ProfilerCategory Render => new ProfilerCategory(ProfilerUnsafeUtility.CategoryRender);
/// <summary>
/// Default category for all ProfilerMarkers defined in scripting code.
/// </summary>
public static ProfilerCategory Scripts => new ProfilerCategory(ProfilerUnsafeUtility.CategoryScripts);
/// <summary>
/// A ProfilerMarker that belongs to the UI system.
/// </summary>
public static ProfilerCategory GUI => new ProfilerCategory(ProfilerUnsafeUtility.CategoryGUI);
/// <summary>
/// A ProfilerMarker that belongs to the Physics system.
/// </summary>
public static ProfilerCategory Physics => new ProfilerCategory(ProfilerUnsafeUtility.CategoryPhysics);
/// <summary>
/// A ProfilerMarker that belongs to the Animation system.
/// </summary>
public static ProfilerCategory Animation => new ProfilerCategory(ProfilerUnsafeUtility.CategoryAnimation);
/// <summary>
/// A ProfilerMarker that belongs to the Ai or NavMesh system.
/// </summary>
public static ProfilerCategory Ai => new ProfilerCategory(ProfilerUnsafeUtility.CategoryAi);
/// <summary>
/// A ProfilerMarker that belongs the to Audio system.
/// </summary>
public static ProfilerCategory Audio => new ProfilerCategory(ProfilerUnsafeUtility.CategoryAudio);
/// <summary>
/// A ProfilerMarker that belongs to the Video system.
/// </summary>
public static ProfilerCategory Video => new ProfilerCategory(ProfilerUnsafeUtility.CategoryVideo);
/// <summary>
/// A ProfilerMarker that belongs to the Particle system.
/// </summary>
public static ProfilerCategory Particles => new ProfilerCategory(ProfilerUnsafeUtility.CategoryParticles);
/// <summary>
/// A ProfilerMarker that belongs to the Lighting system.
/// </summary>
public static ProfilerCategory Lighting => new ProfilerCategory(ProfilerUnsafeUtility.CategoryLightning);
/// <summary>
/// A ProfilerMarker that belongs to the Networking system.
/// </summary>
public static ProfilerCategory Network => new ProfilerCategory(ProfilerUnsafeUtility.CategoryNetwork);
/// <summary>
/// A ProfilerMarker that belongs to the Loading or Streaming system.
/// </summary>
public static ProfilerCategory Loading => new ProfilerCategory(ProfilerUnsafeUtility.CategoryLoading);
/// <summary>
/// A ProfilerMarker that belongs to the VR system.
/// </summary>
public static ProfilerCategory Vr => new ProfilerCategory(ProfilerUnsafeUtility.CategoryVr);
/// <summary>
/// A ProfilerMarker that belongs to the Input system.
/// </summary>
public static ProfilerCategory Input => new ProfilerCategory(ProfilerUnsafeUtility.CategoryInput);
/// <summary>
/// Utility operator that simplifies usage of the ProfilerCategory with ProfilerUnsafeUtility.
/// </summary>
/// <param name="category"></param>
/// <returns>ProfilerCategory value as UInt16.</returns>
public static implicit operator ushort(ProfilerCategory category)
{
return category.m_Category;
}
}
}
#endif

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ccb80ec401f643340bbf9917e0af44a6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,73 @@
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
{
/// <summary>
/// Reports a value of an integer or floating point type to the Unity Profiler.
/// </summary>
/// <typeparam name="T">int, uint, long, ulong, float or double type.</typeparam>
#if ENABLE_PROFILER
[StructLayout(LayoutKind.Sequential)]
#else
[StructLayout(LayoutKind.Sequential, Size = 0)]
#endif
public readonly struct ProfilerCounter<T> where T : unmanaged
{
#if ENABLE_PROFILER
[NativeDisableUnsafePtrRestriction]
[NonSerialized]
readonly IntPtr m_Ptr;
[NonSerialized]
readonly byte m_Type;
#endif
/// <summary>
/// Constructs a **ProfilerCounter** that is reported to the Unity Profiler whenever you call Sample().
/// </summary>
/// <param name="category">Profiler category.</param>
/// <param name="name">Name of ProfilerCounter.</param>
/// <param name="dataUnit">Value unit type.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ProfilerCounter(ProfilerCategory category, string name, ProfilerMarkerDataUnit dataUnit)
{
#if ENABLE_PROFILER
m_Type = ProfilerUtility.GetProfilerMarkerDataType<T>();
m_Ptr = ProfilerUnsafeUtility.CreateMarker(name, category, MarkerFlags.Counter, 1);
ProfilerUnsafeUtility.SetMarkerMetadata(m_Ptr, 0, null, m_Type, (byte)dataUnit);
#endif
}
/// <summary>
/// Sends the value to Unity Profiler immediately.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
/// <param name="value">The value to send to the profiler.</param>
[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<T>(),
Ptr = UnsafeUtility.AddressOf(ref value)
};
ProfilerUnsafeUtility.SingleSampleWithMetadata(m_Ptr, 1, &data);
}
#endif
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d58c38c3c63b0d245b4929c913c48643
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,161 @@
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
{
/// <summary>
/// Reports a value of an integral or floating point type to the Unity Profiler.
/// </summary>
/// <typeparam name="T">int, uint, long, ulong, float or double type.</typeparam>
#if ENABLE_PROFILER
[StructLayout(LayoutKind.Sequential)]
#else
[StructLayout(LayoutKind.Sequential, Size = 1)]
#endif
public readonly struct ProfilerCounterValue<T> where T : unmanaged
{
#if ENABLE_PROFILER
[NativeDisableUnsafePtrRestriction]
[NonSerialized]
readonly unsafe T* m_Value;
#endif
/// <summary>
/// Constructs a **ProfilerCounter** that belongs to the generic ProfilerCategory.Scripts category. It is reported at the end of CPU frame to the Unity Profiler.
/// </summary>
/// <param name="name">Name of ProfilerCounter.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ProfilerCounterValue(string name)
{
#if ENABLE_PROFILER
byte dataType = ProfilerUtility.GetProfilerMarkerDataType<T>();
unsafe
{
m_Value = (T*)ProfilerUnsafeUtility.CreateCounterValue(out var counterPtr, name, ProfilerUnsafeUtility.CategoryScripts, MarkerFlags.Default, dataType, (byte)ProfilerMarkerDataUnit.Undefined, UnsafeUtility.SizeOf<T>(), ProfilerCounterOptions.FlushOnEndOfFrame);
}
#endif
}
/// <summary>
/// Constructs a **ProfilerCounter** that belongs to the generic ProfilerCategory.Scripts category. It is reported at the end of CPU frame to the Unity Profiler.
/// </summary>
/// <param name="name">Name of ProfilerCounter.</param>
/// <param name="dataUnit">Value unit type.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ProfilerCounterValue(string name, ProfilerMarkerDataUnit dataUnit)
{
#if ENABLE_PROFILER
byte dataType = ProfilerUtility.GetProfilerMarkerDataType<T>();
unsafe
{
m_Value = (T*)ProfilerUnsafeUtility.CreateCounterValue(out var counterPtr, name, ProfilerUnsafeUtility.CategoryScripts, MarkerFlags.Default, dataType, (byte)dataUnit, UnsafeUtility.SizeOf<T>(), ProfilerCounterOptions.FlushOnEndOfFrame);
}
#endif
}
/// <summary>
/// Constructs a **ProfilerCounter** that belongs to generic ProfilerCategory.Scripts category.
/// </summary>
/// <param name="name">Name of ProfilerCounter.</param>
/// <param name="dataUnit">Value unit type.</param>
/// <param name="counterOptions">ProfilerCounter options.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ProfilerCounterValue(string name, ProfilerMarkerDataUnit dataUnit, ProfilerCounterOptions counterOptions)
{
#if ENABLE_PROFILER
byte dataType = ProfilerUtility.GetProfilerMarkerDataType<T>();
unsafe
{
m_Value = (T*)ProfilerUnsafeUtility.CreateCounterValue(out var counterPtr, name, ProfilerUnsafeUtility.CategoryScripts, MarkerFlags.Default, dataType, (byte)dataUnit, UnsafeUtility.SizeOf<T>(), counterOptions);
}
#endif
}
/// <summary>
/// Constructs a **ProfilerCounter** that is reported at the end of CPU frame to the Unity Profiler.
/// </summary>
/// <param name="category">Profiler category.</param>
/// <param name="name">Name of ProfilerCounter.</param>
/// <param name="dataUnit">Value unit type.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ProfilerCounterValue(ProfilerCategory category, string name, ProfilerMarkerDataUnit dataUnit)
{
#if ENABLE_PROFILER
byte dataType = ProfilerUtility.GetProfilerMarkerDataType<T>();
unsafe
{
m_Value = (T*)ProfilerUnsafeUtility.CreateCounterValue(out var counterPtr, name, category, MarkerFlags.Default, dataType, (byte)dataUnit, UnsafeUtility.SizeOf<T>(), ProfilerCounterOptions.FlushOnEndOfFrame);
}
#endif
}
/// <summary>
/// Constructs a **ProfilerCounter**.
/// </summary>
/// <param name="category">Profiler category.</param>
/// <param name="name">Name of ProfilerCounter.</param>
/// <param name="dataUnit">Value unit type.</param>
/// <param name="counterOptions">ProfilerCounter options.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ProfilerCounterValue(ProfilerCategory category, string name, ProfilerMarkerDataUnit dataUnit, ProfilerCounterOptions counterOptions)
{
#if ENABLE_PROFILER
byte dataType = ProfilerUtility.GetProfilerMarkerDataType<T>();
unsafe
{
m_Value = (T*)ProfilerUnsafeUtility.CreateCounterValue(out var counterPtr, name, category, MarkerFlags.Default, dataType, (byte)dataUnit, UnsafeUtility.SizeOf<T>(), counterOptions);
}
#endif
}
/// <summary>
/// Gets or sets value of the ProfilerCounter.
/// </summary>
/// <remarks>Returns 0 and is not implemented in Release Players.</remarks>
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
}
}
/// <summary>
/// Sends the value to Unity Profiler immediately.
/// </summary>
[Conditional("ENABLE_PROFILER")]
public void Sample()
{
#if ENABLE_PROFILER
unsafe
{
ProfilerUnsafeUtility.FlushCounterValue(m_Value);
}
#endif
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3fc8749a5a33bb94aaca8a1ece0d20eb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,166 @@
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
{
/// <summary>
/// Use ProfilerMarker&lt;TP1&gt; to mark up script code blocks for the Unity Profiler.
///
/// You can pass a single integral or floating point parameter alongside the Begin event.
/// </summary>
/// <typeparam name="TP1">int, uint, long, ulong, float or double type.</typeparam>
#if ENABLE_PROFILER
[StructLayout(LayoutKind.Sequential)]
#else
[StructLayout(LayoutKind.Sequential, Size = 1)]
#endif
public readonly struct ProfilerMarker<TP1> where TP1 : unmanaged
{
#if ENABLE_PROFILER
[NativeDisableUnsafePtrRestriction]
[NonSerialized]
readonly IntPtr m_Ptr;
// m_P1Type is initialized as a member variable to support usage in Burst.
// Avoiding cctor generation allows us to:
// 1) Use generic approach.
// 2) Skip class static init check in Burst code.
[NonSerialized]
readonly byte m_P1Type;
#endif
/// <summary>
/// Constructs the ProfilerMarker that belongs to the generic ProfilerCategory.Scripts category.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
/// <param name="name">Name of a marker.</param>
/// <param name="param1Name">Name of the first parameter passed to the Begin method.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ProfilerMarker(string name, string param1Name)
{
#if ENABLE_PROFILER
m_P1Type = ProfilerUtility.GetProfilerMarkerDataType<TP1>();
m_Ptr = ProfilerUnsafeUtility.CreateMarker(name, ProfilerUnsafeUtility.CategoryScripts, MarkerFlags.Default, 1);
ProfilerUnsafeUtility.SetMarkerMetadata(m_Ptr, 0, param1Name, m_P1Type, (byte)ProfilerMarkerDataUnit.Undefined);
#endif
}
/// <summary>
/// Constructs the ProfilerMarker.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
/// <param name="category">Profiler category.</param>
/// <param name="name">Name of a marker.</param>
/// <param name="param1Name">Name of the first parameter passed to the Begin method.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ProfilerMarker(ProfilerCategory category, string name, string param1Name)
{
#if ENABLE_PROFILER
m_P1Type = ProfilerUtility.GetProfilerMarkerDataType<TP1>();
m_Ptr = ProfilerUnsafeUtility.CreateMarker(name, category, MarkerFlags.Default, 1);
ProfilerUnsafeUtility.SetMarkerMetadata(m_Ptr, 0, param1Name, m_P1Type, (byte)ProfilerMarkerDataUnit.Undefined);
#endif
}
/// <summary>
/// Begins profiling a piece of code marked with the ProfilerMarker instance.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
/// <param name="p1">Additional context parameter.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_PROFILER")]
[Pure]
public unsafe void Begin(TP1 p1)
{
#if ENABLE_PROFILER
var data = new ProfilerMarkerData
{
Type = m_P1Type,
Size = (uint)UnsafeUtility.SizeOf<TP1>(),
Ptr = UnsafeUtility.AddressOf(ref p1)
};
ProfilerUnsafeUtility.BeginSampleWithMetadata(m_Ptr, 1, &data);
#endif
}
/// <summary>
/// Ends profiling a piece of code marked with the ProfilerMarker instance.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_PROFILER")]
[Pure]
public void End()
{
#if ENABLE_PROFILER
ProfilerUnsafeUtility.EndSample(m_Ptr);
#endif
}
/// <summary>
/// A helper struct that automatically calls End on Dispose. Used with the *using* statement.
/// </summary>
public readonly struct AutoScope : IDisposable
{
#if ENABLE_PROFILER
readonly ProfilerMarker<TP1> m_Marker;
#endif
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal AutoScope(ProfilerMarker<TP1> marker, TP1 p1)
{
#if ENABLE_PROFILER
m_Marker = marker;
m_Marker.Begin(p1);
#endif
}
/// <summary>
/// Calls ProfilerMarker.End.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Dispose()
{
#if ENABLE_PROFILER
m_Marker.End();
#endif
}
}
/// <summary>
/// Profiles a piece of code enclosed within the *using* statement.
/// </summary>
/// <remarks>Returns *null* in Release Players.</remarks>
/// <param name="p1">Additional context parameter.</param>
/// <returns>IDisposable struct which calls End on Dispose.</returns>
/// <example>
/// <code>
/// using (profilerMarker.Auto(enemies.Count))
/// {
/// var blastRadius2 = blastRadius * blastRadius;
/// for (int i = 0; i &lt; enemies.Count; ++i)
/// {
/// var r2 = (enemies[i].Pos - blastPos).sqrMagnitude;
/// if (r2 &lt; blastRadius2)
/// enemies[i].Dispose();
/// }
/// }
/// </code>
/// </example>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Pure]
public AutoScope Auto(TP1 p1)
{
#if ENABLE_PROFILER
return new AutoScope(this, p1);
#else
return default;
#endif
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a42a172397f9187499b8ec7a93c56e85
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,187 @@
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
{
/// <summary>
/// Use ProfilerMarker&lt;TP1, TP2&gt; to mark up script code blocks for the Unity Profiler.
///
/// You can pass two integral or floating point parameters alongside the Begin event.
/// The following types are supported as parameters:
/// * int
/// * uint
/// * long
/// * ulong
/// * float
/// * double
/// </summary>
/// <typeparam name="TP1">Type of the first parameter.</typeparam>
/// <typeparam name="TP2">Type of the second parameter.</typeparam>
#if ENABLE_PROFILER
[StructLayout(LayoutKind.Sequential)]
#else
[StructLayout(LayoutKind.Sequential, Size = 1)]
#endif
public readonly struct ProfilerMarker<TP1, TP2>
where TP1 : unmanaged
where TP2 : unmanaged
{
#if ENABLE_PROFILER
[NativeDisableUnsafePtrRestriction]
[NonSerialized]
readonly IntPtr m_Ptr;
// m_P1Type is initialized as a member variable to support usage in Burst.
// Avoiding cctor generation allows us to:
// 1) Use generic approach.
// 2) Skip class static init check in Burst code.
[NonSerialized]
readonly byte m_P1Type;
[NonSerialized]
readonly byte m_P2Type;
#endif
/// <summary>
/// Constructs the ProfilerMarker that belongs to the generic ProfilerCategory.Scripts category.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
/// <param name="name">Name of a marker.</param>
/// <param name="param1Name">Name of the first parameter.</param>
/// <param name="param2Name">Name of the second parameter.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ProfilerMarker(string name, string param1Name, string param2Name)
{
#if ENABLE_PROFILER
m_P1Type = ProfilerUtility.GetProfilerMarkerDataType<TP1>();
m_P2Type = ProfilerUtility.GetProfilerMarkerDataType<TP2>();
m_Ptr = ProfilerUnsafeUtility.CreateMarker(name, ProfilerUnsafeUtility.CategoryScripts, MarkerFlags.Default, 2);
ProfilerUnsafeUtility.SetMarkerMetadata(m_Ptr, 0, param1Name, m_P1Type, (byte)ProfilerMarkerDataUnit.Undefined);
ProfilerUnsafeUtility.SetMarkerMetadata(m_Ptr, 1, param2Name, m_P2Type, (byte)ProfilerMarkerDataUnit.Undefined);
#endif
}
/// <summary>
/// Constructs a ProfilerMarker.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
/// <param name="category">Profiler category.</param>
/// <param name="name">Name of a marker.</param>
/// <param name="param1Name">Name of the first parameter.</param>
/// <param name="param2Name">Name of the second parameter.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ProfilerMarker(ProfilerCategory category, string name, string param1Name, string param2Name)
{
#if ENABLE_PROFILER
m_P1Type = ProfilerUtility.GetProfilerMarkerDataType<TP1>();
m_P2Type = ProfilerUtility.GetProfilerMarkerDataType<TP2>();
m_Ptr = ProfilerUnsafeUtility.CreateMarker(name, category, MarkerFlags.Default, 2);
ProfilerUnsafeUtility.SetMarkerMetadata(m_Ptr, 0, param1Name, m_P1Type, (byte)ProfilerMarkerDataUnit.Undefined);
ProfilerUnsafeUtility.SetMarkerMetadata(m_Ptr, 1, param2Name, m_P2Type, (byte)ProfilerMarkerDataUnit.Undefined);
#endif
}
/// <summary>
/// Begins profiling a piece of code marked with the ProfilerMarker instance.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
/// <param name="p1">The first context parameter.</param>
/// <param name="p2">The second context parameter.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_PROFILER")]
[Pure]
public unsafe void Begin(TP1 p1, TP2 p2)
{
#if ENABLE_PROFILER
var data = stackalloc ProfilerMarkerData[2];
data[0].Type = m_P1Type;
data[0].Size = (uint)UnsafeUtility.SizeOf<TP1>();
data[0].Ptr = UnsafeUtility.AddressOf(ref p1);
data[1].Type = m_P2Type;
data[1].Size = (uint)UnsafeUtility.SizeOf<TP2>();
data[1].Ptr = UnsafeUtility.AddressOf(ref p2);
ProfilerUnsafeUtility.BeginSampleWithMetadata(m_Ptr, 2, data);
#endif
}
/// <summary>
/// Ends profiling a piece of code marked with the ProfilerMarker instance.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_PROFILER")]
[Pure]
public void End()
{
#if ENABLE_PROFILER
ProfilerUnsafeUtility.EndSample(m_Ptr);
#endif
}
/// <summary>
/// A helper struct that automatically calls End on Dispose. Used with the *using* statement.
/// </summary>
public readonly struct AutoScope : IDisposable
{
#if ENABLE_PROFILER
readonly ProfilerMarker<TP1, TP2> m_Marker;
#endif
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal AutoScope(ProfilerMarker<TP1, TP2> marker, TP1 p1, TP2 p2)
{
#if ENABLE_PROFILER
m_Marker = marker;
m_Marker.Begin(p1, p2);
#endif
}
/// <summary>
/// Calls ProfilerMarker.End.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Dispose()
{
#if ENABLE_PROFILER
m_Marker.End();
#endif
}
}
/// <summary>
/// Profiles a piece of code enclosed within a *using* statement.
/// </summary>
/// <remarks>Returns *null* in Release Players.</remarks>
/// <param name="p1">The first context parameter.</param>
/// <param name="p2">The second context parameter.</param>
/// <returns>IDisposable struct which calls End on Dispose.</returns>
/// <example>
/// <code>
/// using (profilerMarker.Auto(enemies.Count, blastRadius))
/// {
/// var blastRadius2 = blastRadius * blastRadius;
/// for (int i = 0; i &lt; enemies.Count; ++i)
/// {
/// var r2 = (enemies[i].Pos - blastPos).sqrMagnitude;
/// if (r2 &lt; blastRadius2)
/// enemies[i].Dispose();
/// }
/// }
/// </code>
/// </example>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AutoScope Auto(TP1 p1, TP2 p2)
{
#if ENABLE_PROFILER
return new AutoScope(this, p1, p2);
#else
return default;
#endif
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 44423c297b53ceb48b955e8f2335a449
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,202 @@
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
{
/// <summary>
/// Use ProfilerMarker&lt;TP1&gt; to mark up script code blocks for the Unity Profiler.
///
/// You can pass three integral or floating point parameters alongside the Begin event.
/// The following types are supported as parameters:
/// * int
/// * uint
/// * long
/// * ulong
/// * float
/// * double
/// </summary>
/// <typeparam name="TP1">Type of the first parameter.</typeparam>
/// <typeparam name="TP2">Type of the second parameter.</typeparam>
/// <typeparam name="TP3">Type of the third parameter.</typeparam>
#if ENABLE_PROFILER
[StructLayout(LayoutKind.Sequential)]
#else
[StructLayout(LayoutKind.Sequential, Size = 1)]
#endif
public readonly struct ProfilerMarker<TP1, TP2, TP3>
where TP1 : unmanaged
where TP2 : unmanaged
where TP3 : unmanaged
{
#if ENABLE_PROFILER
[NativeDisableUnsafePtrRestriction]
[NonSerialized]
readonly IntPtr m_Ptr;
// m_P1Type is initialized as a member variable to support usage in Burst.
// Avoiding cctor generation allows us to:
// 1) Use generic approach.
// 2) Skip class static init check in Burst code.
[NonSerialized]
readonly byte m_P1Type;
[NonSerialized]
readonly byte m_P2Type;
[NonSerialized]
readonly byte m_P3Type;
#endif
/// <summary>
/// Constructs a ProfilerMarker that belongs to the generic ProfilerCategory.Scripts category.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
/// <param name="name">Name of a marker.</param>
/// <param name="param1Name">Name of the first parameter.</param>
/// <param name="param2Name">Name of the second parameter.</param>
/// <param name="param3Name">Name of the third parameter.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ProfilerMarker(string name, string param1Name, string param2Name, string param3Name)
{
#if ENABLE_PROFILER
m_P1Type = ProfilerUtility.GetProfilerMarkerDataType<TP1>();
m_P2Type = ProfilerUtility.GetProfilerMarkerDataType<TP2>();
m_P3Type = ProfilerUtility.GetProfilerMarkerDataType<TP3>();
m_Ptr = ProfilerUnsafeUtility.CreateMarker(name, ProfilerUnsafeUtility.CategoryScripts, MarkerFlags.Default, 3);
ProfilerUnsafeUtility.SetMarkerMetadata(m_Ptr, 0, param1Name, m_P1Type, (byte)ProfilerMarkerDataUnit.Undefined);
ProfilerUnsafeUtility.SetMarkerMetadata(m_Ptr, 1, param2Name, m_P2Type, (byte)ProfilerMarkerDataUnit.Undefined);
ProfilerUnsafeUtility.SetMarkerMetadata(m_Ptr, 2, param3Name, m_P3Type, (byte)ProfilerMarkerDataUnit.Undefined);
#endif
}
/// <summary>
/// Constructs a ProfilerMarker.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
/// <param name="category">Profiler category.</param>
/// <param name="name">Name of a marker.</param>
/// <param name="param1Name">Name of the first parameter.</param>
/// <param name="param2Name">Name of the second parameter.</param>
/// <param name="param3Name">Name of the third parameter.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ProfilerMarker(ProfilerCategory category, string name, string param1Name, string param2Name, string param3Name)
{
#if ENABLE_PROFILER
m_P1Type = ProfilerUtility.GetProfilerMarkerDataType<TP1>();
m_P2Type = ProfilerUtility.GetProfilerMarkerDataType<TP2>();
m_P3Type = ProfilerUtility.GetProfilerMarkerDataType<TP3>();
m_Ptr = ProfilerUnsafeUtility.CreateMarker(name, category, MarkerFlags.Default, 3);
ProfilerUnsafeUtility.SetMarkerMetadata(m_Ptr, 0, param1Name, m_P1Type, (byte)ProfilerMarkerDataUnit.Undefined);
ProfilerUnsafeUtility.SetMarkerMetadata(m_Ptr, 1, param2Name, m_P2Type, (byte)ProfilerMarkerDataUnit.Undefined);
ProfilerUnsafeUtility.SetMarkerMetadata(m_Ptr, 2, param3Name, m_P3Type, (byte)ProfilerMarkerDataUnit.Undefined);
#endif
}
/// <summary>
/// Begin profiling a piece of code marked with the ProfilerMarker instance.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
/// <param name="p1">The first context parameter.</param>
/// <param name="p2">The second context parameter.</param>
/// <param name="p3">The third context parameter.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_PROFILER")]
[Pure]
public unsafe void Begin(TP1 p1, TP2 p2, TP3 p3)
{
#if ENABLE_PROFILER
var data = stackalloc ProfilerMarkerData[3];
data[0].Type = m_P1Type;
data[0].Size = (uint)UnsafeUtility.SizeOf<TP1>();
data[0].Ptr = UnsafeUtility.AddressOf(ref p1);
data[1].Type = m_P2Type;
data[1].Size = (uint)UnsafeUtility.SizeOf<TP2>();
data[1].Ptr = UnsafeUtility.AddressOf(ref p2);
data[2].Type = m_P3Type;
data[2].Size = (uint)UnsafeUtility.SizeOf<TP3>();
data[2].Ptr = UnsafeUtility.AddressOf(ref p3);
ProfilerUnsafeUtility.BeginSampleWithMetadata(m_Ptr, 3, data);
#endif
}
/// <summary>
/// End profiling a piece of code marked with the ProfilerMarker instance.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_PROFILER")]
[Pure]
public void End()
{
#if ENABLE_PROFILER
ProfilerUnsafeUtility.EndSample(m_Ptr);
#endif
}
/// <summary>
/// A helper struct that automatically calls End on Dispose and is used with ''using'' statement.
/// </summary>
public readonly struct AutoScope : IDisposable
{
#if ENABLE_PROFILER
readonly ProfilerMarker<TP1, TP2, TP3> m_Marker;
#endif
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal AutoScope(ProfilerMarker<TP1, TP2, TP3> marker, TP1 p1, TP2 p2, TP3 p3)
{
#if ENABLE_PROFILER
m_Marker = marker;
m_Marker.Begin(p1, p2, p3);
#endif
}
/// <summary>
/// Calls ProfilerMarker.End.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Dispose()
{
#if ENABLE_PROFILER
m_Marker.End();
#endif
}
}
/// <summary>
/// Use to profile a piece of code enclosed within *using* statement.
/// </summary>
/// <remarks>Returns *null* in Release Players.</remarks>
/// <param name="p1">The first context parameter.</param>
/// <param name="p2">The second context parameter.</param>
/// <param name="p3">The third context parameter.</param>
/// <returns>IDisposable struct which calls End on Dispose.</returns>
/// <example>
/// <code>
/// using (profilerMarker.Auto(enemies.Count, blastRadius, blastPos.x))
/// {
/// var blastRadius2 = blastRadius * blastRadius;
/// for (int i = 0; i &lt; enemies.Count; ++i)
/// {
/// var r2 = (enemies[i].Pos - blastPos).sqrMagnitude;
/// if (r2 &lt; blastRadius2)
/// enemies[i].Dispose();
/// }
/// }
/// </code>
/// </example>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public AutoScope Auto(TP1 p1, TP2 p2, TP3 p3)
{
#if ENABLE_PROFILER
return new AutoScope(this, p1, p2, p3);
#else
return default;
#endif
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e4bb7558d4e98ad4c938246fe549cdb7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,155 @@
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Profiling.LowLevel;
using Unity.Profiling.LowLevel.Unsafe;
namespace Unity.Profiling
{
/// <summary>
/// Provides an extension to the ProfilerMarker API to accommodate a single additional parameter to the Begin method.
/// </summary>
public static class ProfilerMarkerExtension
{
/// <summary>
/// Begin profiling a piece of code marked with the ProfilerMarker instance.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
/// <param name="marker">ProfilerMarker instance.</param>
/// <param name="metadata">''int'' parameter.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_PROFILER")]
[Pure]
public static unsafe void Begin(this ProfilerMarker marker, int metadata)
{
var data = new ProfilerMarkerData
{
Type = (byte)ProfilerMarkerDataType.Int32,
Size = (uint)UnsafeUtility.SizeOf<int>(),
Ptr = &metadata
};
ProfilerUnsafeUtility.BeginSampleWithMetadata(marker.Handle, 1, &data);
}
/// <summary>
/// Begin profiling a piece of code marked with the ProfilerMarker instance.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
/// <param name="marker">ProfilerMarker instance.</param>
/// <param name="metadata">''uint'' parameter.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_PROFILER")]
[Pure]
public static unsafe void Begin(this ProfilerMarker marker, uint metadata)
{
var data = new ProfilerMarkerData
{
Type = (byte)ProfilerMarkerDataType.UInt32,
Size = (uint)UnsafeUtility.SizeOf<uint>(),
Ptr = &metadata
};
ProfilerUnsafeUtility.BeginSampleWithMetadata(marker.Handle, 1, &data);
}
/// <summary>
/// Begin profiling a piece of code marked with the ProfilerMarker instance.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
/// <param name="marker">ProfilerMarker instance.</param>
/// <param name="metadata">''long'' parameter.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_PROFILER")]
[Pure]
public static unsafe void Begin(this ProfilerMarker marker, long metadata)
{
var data = new ProfilerMarkerData
{
Type = (byte)ProfilerMarkerDataType.Int64,
Size = (uint)UnsafeUtility.SizeOf<long>(),
Ptr = &metadata
};
ProfilerUnsafeUtility.BeginSampleWithMetadata(marker.Handle, 1, &data);
}
/// <summary>
/// Begin profiling a piece of code marked with the ProfilerMarker instance.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
/// <param name="marker">ProfilerMarker instance.</param>
/// <param name="metadata">''ulong'' parameter.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_PROFILER")]
[Pure]
public static unsafe void Begin(this ProfilerMarker marker, ulong metadata)
{
var data = new ProfilerMarkerData
{
Type = (byte)ProfilerMarkerDataType.UInt64,
Size = (uint)UnsafeUtility.SizeOf<ulong>(),
Ptr = &metadata
};
ProfilerUnsafeUtility.BeginSampleWithMetadata(marker.Handle, 1, &data);
}
/// <summary>
/// Begin profiling a piece of code marked with the ProfilerMarker instance.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
/// <param name="marker">ProfilerMarker instance.</param>
/// <param name="metadata">''float'' parameter.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_PROFILER")]
[Pure]
public static unsafe void Begin(this ProfilerMarker marker, float metadata)
{
var data = new ProfilerMarkerData
{
Type = (byte)ProfilerMarkerDataType.Float,
Size = (uint)UnsafeUtility.SizeOf<float>(),
Ptr = &metadata
};
ProfilerUnsafeUtility.BeginSampleWithMetadata(marker.Handle, 1, &data);
}
/// <summary>
/// Begin profiling a piece of code marked with the ProfilerMarker instance.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
/// <param name="marker">ProfilerMarker instance.</param>
/// <param name="metadata">''double'' parameter.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_PROFILER")]
[Pure]
public static unsafe void Begin(this ProfilerMarker marker, double metadata)
{
var data = new ProfilerMarkerData
{
Type = (byte)ProfilerMarkerDataType.Double,
Size = (uint)UnsafeUtility.SizeOf<double>(),
Ptr = &metadata
};
ProfilerUnsafeUtility.BeginSampleWithMetadata(marker.Handle, 1, &data);
}
/// <summary>
/// Begin profiling a piece of code marked with the ProfilerMarker instance.
/// </summary>
/// <remarks>Does nothing in Release Players.</remarks>
/// <param name="marker">ProfilerMarker instance.</param>
/// <param name="metadata">''string'' parameter.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_PROFILER")]
[Pure]
public static unsafe void Begin(this ProfilerMarker marker, string metadata)
{
var data = new ProfilerMarkerData { Type = (byte)ProfilerMarkerDataType.String16 };
fixed(char* c = metadata)
{
data.Size = ((uint)metadata.Length + 1) * 2;
data.Ptr = c;
ProfilerUnsafeUtility.BeginSampleWithMetadata(marker.Handle, 1, &data);
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6b64b28462013f640ac8d0ab82fe61f7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,31 @@
using System;
using Unity.Profiling.LowLevel;
namespace Unity.Profiling
{
struct ProfilerUtility
{
public static byte GetProfilerMarkerDataType<T>()
{
switch (Type.GetTypeCode(typeof(T)))
{
case TypeCode.Int32:
return (byte)ProfilerMarkerDataType.Int32;
case TypeCode.UInt32:
return (byte)ProfilerMarkerDataType.UInt32;
case TypeCode.Int64:
return (byte)ProfilerMarkerDataType.Int64;
case TypeCode.UInt64:
return (byte)ProfilerMarkerDataType.UInt64;
case TypeCode.Single:
return (byte)ProfilerMarkerDataType.Float;
case TypeCode.Double:
return (byte)ProfilerMarkerDataType.Double;
case TypeCode.String:
return (byte)ProfilerMarkerDataType.String16;
default:
throw new ArgumentException($"Type {typeof(T)} is unsupported by ProfilerCounter.");
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ec67f3c00433a81428ae8331f3a1c0fe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,13 @@
{
"name": "Unity.Profiling.Core",
"references": [],
"optionalUnityReferences": [
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": true,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": []
}

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b46779583a009f04ba9f5f31d0e7e6ac
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: