Adaug proiectul Unity

This commit is contained in:
2026-11-01 23:39:55 +02:00
parent cb14d9d37d
commit 863eac8f2c
23463 changed files with 5412601 additions and 0 deletions
@@ -0,0 +1,38 @@
# Changelog
All notable changes to this package will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [1.0.2] - 2022-03-10
### Changed
- Removed 'preview package' paragraph from documentation.
## [1.0.1] - 2021-09-03
### Changed
- Added direct install link to the documentation.
## [1.0.0] - 2021-08-30
### Fixed
- Made structs layout to be compatible with Burst in Release Players.
## [1.0.0-pre.1] - 2021-02-16
### Fixed
- Fixed ProfilerMarker with 3 parameters being configured as for 2 parameters.
### Removed
- ProfilerCounter constructor with MarkerFlags.
## [0.2.1-preview.1] - 2020-08-25
### Fixed
- ProfilerMarker and ProfilerCounter usage in release Player builds.
## [0.2.0-preview.1] - 2020-08-18
### Added
- ProfilerCounter and ProfilerCounterValue API.
- Profiler counters documentation and usage guide.
## [0.1.0-preview.1] - 2020-05-28
### Added
- This is the first release of *Unity Profiling Core Package*.
- ProfilerMarker API with metadata support.
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d171e58a276f671498761bef2a559e96
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,5 @@
* [Unity Profiling Core Package](index.md)
* [What's new](whats-new.md)
* [Upgrade guide](upgrade-guide.md)
* [ProfilerMarker API guide](profilermarker-guide.md)
* [Profiler Counter API guide](profilercounter-guide.md)
@@ -0,0 +1,24 @@
apiRules:
- exclude:
# inherited Object methods
uidRegex: ^System\.Object\..*$
type: Method
- exclude:
# mentioning types from System.* namespace
uidRegex: ^System\..*$
type: Type
- exclude:
hasAttribute:
uid: System.ObsoleteAttribute
type: Member
- exclude:
hasAttribute:
uid: System.ObsoleteAttribute
type: Type
- exclude:
uidRegex: Tests$
type: Namespace
- exclude:
# ProfilerMarker.Auto helper struct
uidRegex: ^Unity.Profiling.ProfilerMarker.*AutoScope$
type: Type
@@ -0,0 +1,18 @@
# About Unity Profiling Core
Use the Unity Profiling Core package to add contextual information to the [Unity Profiler](https://docs.unity3d.com/Manual/Profiler.html) captures. You can use the [Scripting APIs](https://docs.unity3d.com/Packages/com.unity.profiling.core@latest?subfolder=/api/index.html) provided with the Unity Profiling Core package to add a string or number to a Profiler sample or pass custom data to the Profiler data stream to later use in the Editor.
## Installation
To install this package, follow the instructions in the [Package Manager documentation](https://docs.unity3d.com/Manual/upm-ui-install.html). The Unity Profiling Core package is not discoverable in the Package Manager UI because it is a core package. Therefore the recommended installation method is to [add the package by name](https://docs.unity3d.com/2021.2/Documentation/Manual/upm-ui-quick.html), which is `com.unity.profiling.core`. If you are using Unity 2021.2.0a5 or newer, you can also install it via [this link](com.unity3d.kharma:upmpackage/com.unity.profiling.core).
![Install Package By Name](images/install_package_by_name.png)<br/>*Install package by name.*
## Requirements
This version of Unity Profiling Core is compatible with the following versions of the Unity Editor:
* 2020.1 and later
## Helpful links
If you are new to Unity Profiling Core, or have a question after reading the documentation, you can:
* Watch the [Tutorials](https://learn.unity.com/tutorial/introduction-to-the-profiler) here.
* Join our [support forum](https://forum.unity.com/forums/profiler-previews.199/).
@@ -0,0 +1,189 @@
# Profiler counters API guide
You can use the `ProfilerCounter` or `ProfilerCounterValue` API to track the integral metrics of your application and make them visible in the Unity Profiler or in other code. This is particularly useful if you want to track performance changes in your application, and it speeds up the investigation of performance issues because you can use the information from your Profiler counters in conjunction with Unity built-in counters and instrumentation data.
If you are an Asset Store package developer, you can add Profiler counters to your code to help other developers to understand important performance characteristics of your system, and they can use this information for optimization or budgeting tooling.
The following diagram displays a high level overview of the Profiler counters data flow:
![Profiler counters flow.](images/profilercounter_flow.png)<br/>*Profiler counters flow.*
The [ProfilerRecorder](https://docs.unity3d.com/ScriptReference/Unity.Profiling.ProfilerRecorder.html) API retrieves Profiler counter data in your application code, and the [RawFrameDataView](https://docs.unity3d.com/ScriptReference/Profiling.RawFrameDataView.html) or [HierarchyFrameDataView](https://docs.unity3d.com/ScriptReference/Profiling.HierarchyFrameDataView.html) APIs retrieves Profiler counter data in the Editor code. Additionally, you can visualize this counter data in the Profiler Window by [configuring a custom Profiler Module in the Module Editor](#viewing-counters).
`ProfilerCounter` and `ProfilerCounterValue` support the following types:
* int
* long
* float
* double
## How to pass counter values to the Profiler
The Profiler counters API supports push and pull operations. You can push the value of the counter to the Profiler, or the Profiler can pull the value at the end of the frame.
If your data changes infrequently - for example once per frame, use the `ProfilerCounter` API to push the counter data to the Profiler. If your data changes multiple times per frame, use the `ProfilerCounterValue` API. This makes the Profiler automatically pick up the last value at the end of the frame. The following example shows you how to use these APIs to set up and pass counter values to the Profiler
### 1. Define counters
To pass counter values to the Profiler, you must first define which counters you want to send. The following example uses `ProfilerCounter` for the enemies count because the value changes infrequently. Additionally, the example uses `ProfilerCounterValue` for bullet count because a player or enemies might fire many bullets per frame.
```C#
using Unity.Profiling;
class GameStats
{
public static readonly ProfilerCategory MyProfilerCategory = ProfilerCategory.Scripts;
public static readonly ProfilerCounter<int> EnemyCount =
new ProfilerCounter<int>(MyProfilerCategory, "Enemy Count", ProfilerMarkerDataUnit.Count);
public static ProfilerCounterValue<int> BulletCount =
new ProfilerCounterValue<int>(MyProfilerCategory, "Bullet Count",
ProfilerMarkerDataUnit.Count, ProfilerCounterOptions.FlushOnEndOfFrame);
}
```
### 2. Update the value
The next example assumes that the `GameManager` class handles high level logic and knows about enemies. To update the value of the counter, in the `Update` or `LateUpdate` method (depending on when the logic is performed with spawning or destroying enemies), you can use `Sample` method to push the enemies count value to the Profiler.
```c#
using UnityEngine;
using Unity.Profiling;
class GameManager : MonoBehaviour
{
Enemy[] m_Enemies;
void Update()
{
GameStats.EnemyCount.Sample(m_Enemies.Length);
}
}
```
To pass the bullet count to the Profiler, this example assumes that there is a Shell script that manages the bullet lifecycle. It then increases the `GameStats.BulletCount` value in `Awake` and decreases it in `OnDestroy` to give accurate information about the current bullet flow in the game.
```c#
using UnityEngine;
using Unity.Profiling;
public class Shell : MonoBehaviour
{
void Awake()
{
GameStats.BulletCount.Value += 1;
}
void OnDestroy()
{
GameStats.BulletCount.Value -= 1;
}
}
```
>[!NOTE]
>Both `ProfilerCounter` and `ProfilerCounterValue` are compiled out in non-development builds.
<a name="viewing-counters"> </a>
## Viewing the counters in the Profiler Window
You can view the data that `ProfilerCounter` or `ProfilerCounterValue` generates in the Profiler Window in a custom Profiler Module. This might help to visually recognise relationships with other system metrics and identify performance issues quickly. You can use the Module Editor to select built-in or newly added counters for the visualization. To open the Profiler Module Editor, open the Profiler Window (**Window &gt; Analysis &gt; Profiler**) and then select the Profiler Module dropdown in the top left of the window. Click the gear icon, and the Profiler Module Editor opens in a new window.
![Profiler Module Editor](images/profilermoduleeditor.png)<br/>*Profiler Module Editor window.*
You can then view the data in the Profiler Window alongside with other counters.
![Module with custom counters in Profiler Window.](images/mystatsmodule.png)<br/>*Module with custom counters in the Profiler Window.*
>[!NOTE]
>Counters declared as `static` are dynamically initialized in the C# code when a type is initialized and might not be available until they are actually initialized and used. This applies to both Edit and Play Modes.
If you don't see your counters appearing in the Module Editor, record some data with the profiler first until some frames passed that should have send values through these counters.
## Getting counter values in Players
Profiler counters give you an insight into important game or engine system metrics. If you have a continuous integration setup or want to visualize key performance metrics in your application during a test play through you can use the [ProfilerRecorder](https://docs.unity3d.com/ScriptReference/Unity.Profiling.ProfilerRecorder.html) API to get custom Profiler counter values as well as Unity built-in counters.
For example, the following script displays the frame time, Mono/IL2CPP heap size, and total memory that the application uses.
```c#
using System.Collections.Generic;
using System.Text;
using Unity.Profiling;
using UnityEngine;
public class StatsScript : MonoBehaviour
{
string statsText;
ProfilerRecorder systemMemoryRecorder;
ProfilerRecorder gcMemoryRecorder;
ProfilerRecorder mainThreadTimeRecorder;
double GetRecorderFrameAverage(ProfilerRecorder recorder)
{
var samplesCount = recorder.Capacity;
if (samplesCount == 0)
return 0;
double r = 0;
unsafe
{
var samples = stackalloc ProfilerRecorderSample[samplesCount];
recorder.CopyTo(samples, samplesCount);
for (var i = 0; i < samplesCount; ++i)
r += samples[i].Value;
r /= samplesCount;
}
return r;
}
void OnEnable()
{
systemMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "System Used Memory");
gcMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "GC Reserved Memory");
mainThreadTimeRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Internal, "Main Thread", 15);
}
void OnDisable()
{
systemMemoryRecorder.Dispose();
gcMemoryRecorder.Dispose();
mainThreadTimeRecorder.Dispose();
}
void Update()
{
var sb = new StringBuilder(500);
sb.AppendLine($"Frame Time: {GetRecorderFrameAverage(mainThreadTimeRecorder) * (1e-6f):F1} ms");
sb.AppendLine($"GC Memory: {gcMemoryRecorder.LastValue / (1024 * 1024)} MB");
sb.AppendLine($"System Memory: {systemMemoryRecorder.LastValue / (1024 * 1024)} MB");
statsText = sb.ToString();
}
void OnGUI()
{
GUI.TextArea(new Rect(10, 30, 250, 50), statsText);
}
}
```
Don't forget to use `ProfilerRecorder.Dispose()` to free unmanaged resources associated with the `ProfilerRecorder`.
>[!NOTE]
>Not all Profiler counters are available in the Release Players. Use [ProfilerRecorder.Valid](https://docs.unity3d.com/ScriptReference/Unity.Profiling.ProfilerRecorder.Valid.html) to determine if the data is available and that the Profiler can record it. Alternatively, you can use [ProfilerRecorderHandle.GetAvailable](https://docs.unity3d.com/ScriptReference/Unity.Profiling.LowLevel.Unsafe.ProfilerRecorderHandle.GetAvailable.html) to enumerate all available Profiler stats.
## Getting counter values from Profiler Frame data in the Editor
To get Profiler counter values when processing Profiler frame data in the Editor, use the [FrameDataView](https://docs.unity3d.com/ScriptReference/Profiling.FrameDataView.html) API.
You can use the [FrameDataView.GetCounterValueAsInt](https://docs.unity3d.com/ScriptReference/Profiling.FrameDataView.GetCounterValueAsInt.html), [FrameDataView.GetCounterValueAsLong](https://docs.unity3d.com/ScriptReference/Profiling.FrameDataView.GetCounterValueAsLong.html), [FrameDataView.GetCounterValueAsFloat](https://docs.unity3d.com/ScriptReference/Profiling.FrameDataView.GetCounterValueAsFloat.html) and [FrameDataView.GetCounterValueAsDouble](https://docs.unity3d.com/ScriptReference/Profiling.FrameDataView.GetCounterValueAsDouble.html) to get a frame value of the specific counter, like so:
```c#
using UnityEditor.Profiling;
class Example
{
static int ExtractMyCounterValue(FrameDataView frameData, string counterName)
{
var counterMarkerId = frameData.GetMarkerId(counterName);
return frameData.GetCounterValueAsInt(counterMarkerId);
}
}
```
@@ -0,0 +1,117 @@
# ProfilerMarker API guide
Use ProfilerMarker to mark up resource-intensive script code blocks and make them visible in the Unity Profiler.
This can be useful because by default, the built-in Unity Profiler does not profile all method calls. Also, if you enable **Deep Profiling**, it causes a large overhead that significantly slows down your application execution and skews the results.
To use the [ProfilerMarker API](https://docs.unity3d.com/ScriptReference/Unity.Profiling.ProfilerMarker.html), start your code with `ProfilerMarker.Begin()` and end it with `ProfilerMarker.End()` like the following:
```C#
using UnityEngine;
using Unity.Profiling;
public class ProfilerMarkerExample
{
static readonly ProfilerMarker k_MyCodeMarker = new ProfilerMarker("My Code");
void Update() {
k_MyCodeMarker.Begin();
Debug.Log("This code is being profiled");
k_MyCodeMarker.End();
}
}
```
Unity then records and reports that code block's execution time to the Profiler, and displays it in the [CPU Profiler module](https://docs.unity3d.com/Manual/ProfilerCPU.html) without the need to use Deep Profiling. It displays it as a new entry in the **Hierarchy View** of the CPU Profiler module, as follows:
![Profiler sample in Profiler Window.](images/profilerwindow.png)<br/>*Profiler sample in Profiler Window.*
You can also capture this information with the [Recorder profiling API](https://docs.unity3d.com/ScriptReference/Profiling.Recorder.html). During development in the Editor and in Development Players, you can use it to get a performance overview of the different parts of your code and to identify performance issues.
You can add as many Profiler samples as you like: these calls have zero overhead when Unity deploys them in a non-development build. `Begin` and `End` methods are marked with ConditionalAttribute. Unity conditionally compiles them away, and as such, they have zero execution overhead in non-developmenet (Release) builds. The marker field will be present in release build though, taking up memory for it's IntPtr, i.e. 8 Byte.
`ProfilerMarker` represents a named Profiler handle and is the most efficient way of profiling your code. You can use it in any C# code of your application.
## How to add instrumentation to C# code
You can also use `ProfilerMarker.Auto()` in your code to ensure that `ProfilerMarker.End()` is automatically called at the end of the code block. The following calls are equivalent:
```C#
using Unity.Profiling;
public class MySystemClass
{
static readonly ProfilerMarker k_UpdatePerfMarker = new ProfilerMarker("MySystem.Update");
public void Update()
{
k_UpdatePerfMarker.Begin();
// ...
k_UpdatePerfMarker.End();
using (k_UpdatePerfMarker.Auto())
{
// ...
}
}
}
```
`ProfilerMarker.Auto()` can not be compiled out in non-development (Release) builds but just returns null and thus adding minimal overhead.
## How to add integer or floating point parameters to instrumentation sample
Sometimes you might want to provide additional context to your code samples, to identify specific conditions on why the code might have been running for a long time. For example, if your system is carrying out simulations of a number of objects, you can pass the number of objects with a Profiler sample. If you then see an abnormal number along with a long sample duration, that might mean you have to use another thread for simulation or split the CPU work across multiple frames (timeslicing) or even do a game design adjustments to prevent frame drops.
```C#
using Unity.Profiling;
public class MySystemClass
{
static readonly ProfilerMarker<int> k_PreparePerfMarker = new ProfilerMarker<int>("MySystem.Prepare", "Objects Count");
static readonly ProfilerMarker<float> k_SimulatePerfMarker = new ProfilerMarker<float>(ProfilerCategory.Scripts, "MySystem.Simulate", "Objects Density");
public void Update(int objectsCount)
{
k_PreparePerfMarker.Begin(objectsCount);
// ...
k_PreparePerfMarker.End();
using (k_SimulatePerfMarker.Auto(objectsCount * 1.0f))
{
// ...
}
}
}
```
**Note:** The ProfilerMarker supports up to three numeric parameters: [ProfilerMarker\<TP1\>](../api/Unity.Profiling.ProfilerMarker-1.html), [ProfilerMarker\<TP1, TP2\>](../api/Unity.Profiling.ProfilerMarker-2.html) and [ProfilerMarker\<TP1, TP2, TP3\>](../api/Unity.Profiling.ProfilerMarker-3.html).
## How to add string parameter to instrumentation sample
Similarly, when you load level or data files you might want to see the name of the level or file which took longer than expected to process. Use [ProfilerMarkerExtension](../api/Unity.Profiling.ProfilerMarkerExtension.html) methods to pass a string parameter along with a Profiler sample:
```C#
using Unity.Profiling;
public class MySystemClass
{
static readonly ProfilerMarker k_PreparePerfMarker = new ProfilerMarker("MySystem.Prepare");
public void Prepare(string path)
{
k_PreparePerfMarker.Begin(path);
// ...
k_PreparePerfMarker.End();
}
}
```
## Where to see the sample parameters in Profiler Window
The samples that `ProfilerMarker.Begin()/End()` or `ProfilerMarker.Auto` generates are visible in **Timeline View** and **Hierarchy View** of the CPU module in the Profiler Window.
![Profiler sample with metadata in Timeline View.](images/timelineview_metadata.png)<br/>*Profiler sample with metadata in Timeline View.*
![Profiler sample with metadata in Hierarchy View.](images/hierarchyview_metadata.png)<br/>*Profiler sample with metadata in Hierarchy View.*
@@ -0,0 +1,3 @@
# Profiling Core upgrade guide
You do not need to take any actions to upgrade your project to this package version.
@@ -0,0 +1,3 @@
# Profiling Core what's new guide
This is a new package release. In future package versions, this page will display a summary of updates and changes for that version.
@@ -0,0 +1,5 @@
com.unity.profiling.core copyright © 2020 Unity Technologies ApS
Licensed under the Unity Companion License for Unity-dependent projects--see [Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License).
Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. Please review the license for details on these and other terms and conditions.
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 112bbb75cb8d0f34587b23aeb83ad6d8
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,3 @@
# com.unity.profiling.core
Unity Profiling package provides a set of APIs that allows to add instrumentation and performance metrics to C# code for futher analysis in Unity Profiler.
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 818f5671ae3a433488eaec387a0032e1
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0728d61b12f4b1e4fa9299f79f0c3948
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -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
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ccb80ec401f643340bbf9917e0af44a6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -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
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d58c38c3c63b0d245b4929c913c48643
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -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
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3fc8749a5a33bb94aaca8a1ece0d20eb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -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
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a42a172397f9187499b8ec7a93c56e85
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -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
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 44423c297b53ceb48b955e8f2335a449
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -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
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e4bb7558d4e98ad4c938246fe549cdb7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -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);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6b64b28462013f640ac8d0ab82fe61f7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -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.");
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ec67f3c00433a81428ae8331f3a1c0fe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,13 @@
{
"name": "Unity.Profiling.Core",
"references": [],
"optionalUnityReferences": [
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": true,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": []
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b46779583a009f04ba9f5f31d0e7e6ac
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,27 @@
{
"name": "com.unity.profiling.core",
"displayName": "Unity Profiling Core API",
"version": "1.0.3",
"unity": "2020.1",
"description": "The Unity Profiling Core package provides an API for code instrumentation markup, and for profiling statistic collection.",
"keywords": [
"profiler",
"profiling",
"api"
],
"upm": {
"changelog": "### Changed,- Removed 'preview package' paragraph from documentation."
},
"relatedPackages": {
"com.unity.profiling.core.tests": "1.0.2"
},
"upmCi": {
"footprint": "3f39f7351890affc1c40e4b0b9a67372e078404d"
},
"repository": {
"url": "https://github.cds.internal.unity3d.com/unity/profiler.git",
"type": "git",
"revision": "2189ba14439d76a4083f59fae87163b4bdfd49c2"
},
"_fingerprint": "8a49f7027d0618e2cb86aa9e4ed5fb4392e8121a"
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2c9e05a58e554a940ae0417d8ce7384a
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: