using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Profiling;
using UnityEngine.Profiling;
using UnityEngine;
///
/// Profiler Stats reporting helper class. Stores all adaptive performance counters and helper functions.
///
public static class AdaptivePerformanceProfilerStats
{
///
/// Profiler Category is set to scripts for Adaptive Performance.
///
public static readonly ProfilerCategory AdaptivePerformanceProfilerCategory = ProfilerCategory.Scripts;
///
/// Profiler counter to report cpu frametime.
///
public static ProfilerCounter CurrentCPUCounter = new ProfilerCounter(AdaptivePerformanceProfilerCategory, "CPU frametime", ProfilerMarkerDataUnit.TimeNanoseconds);
///
/// Profiler counter to report cpu average frametime.
///
public static ProfilerCounter AvgCPUCounter = new ProfilerCounter(AdaptivePerformanceProfilerCategory, "CPU avg frametime", ProfilerMarkerDataUnit.TimeNanoseconds);
///
/// Profiler counter to report gpu frametime.
///
public static ProfilerCounter CurrentGPUCounter = new ProfilerCounter(AdaptivePerformanceProfilerCategory, "GPU frametime", ProfilerMarkerDataUnit.TimeNanoseconds);
///
/// Profiler counter to report gpu average frametime.
///
public static ProfilerCounter AvgGPUCounter = new ProfilerCounter(AdaptivePerformanceProfilerCategory, "GPU avg frametime", ProfilerMarkerDataUnit.TimeNanoseconds);
///
/// Profiler counter to report cpu performance level.
///
public static ProfilerCounter CurrentCPULevelCounter = new ProfilerCounter(AdaptivePerformanceProfilerCategory, "CPU performance level", ProfilerMarkerDataUnit.Count);
///
/// Profiler counter to report gpu performance level.
///
public static ProfilerCounter CurrentGPULevelCounter = new ProfilerCounter(AdaptivePerformanceProfilerCategory, "GPU performance level", ProfilerMarkerDataUnit.Count);
///
/// Profiler counter to report frametime.
///
public static ProfilerCounter CurrentFrametimeCounter = new ProfilerCounter(AdaptivePerformanceProfilerCategory, "Frametime", ProfilerMarkerDataUnit.TimeNanoseconds);
///
/// Profiler counter to report average frametime.
///
public static ProfilerCounter AvgFrametimeCounter = new ProfilerCounter(AdaptivePerformanceProfilerCategory, "Avg frametime", ProfilerMarkerDataUnit.TimeNanoseconds);
///
/// Profiler counter to report the thermal warning level.
///
public static ProfilerCounter WarningLevelCounter = new ProfilerCounter(AdaptivePerformanceProfilerCategory, "Thermal Warning Level", ProfilerMarkerDataUnit.Count);
///
/// Profiler counter to report the temperature level.
///
public static ProfilerCounter TemperatureLevelCounter = new ProfilerCounter(AdaptivePerformanceProfilerCategory, "Temperature Level", ProfilerMarkerDataUnit.Count);
///
/// Profiler counter to report the temperature trend.
///
public static ProfilerCounter TemperatureTrendCounter = new ProfilerCounter(AdaptivePerformanceProfilerCategory, "Temperature Trend", ProfilerMarkerDataUnit.Count);
///
/// Profiler counter to report the bottleneck.
///
public static ProfilerCounter BottleneckCounter = new ProfilerCounter(AdaptivePerformanceProfilerCategory, "Bottleneck", ProfilerMarkerDataUnit.Count);
///
/// GUID for the Adaptive Performance Profile Module definition.
///
public static readonly Guid kAdaptivePerformanceProfilerModuleGuid = new Guid("42c5aeb7-fb77-4172-a384-34063f1bd332");
///
/// The Scaler data tag defines a tag for the scalers to send them via the emit frame data function.
///
public static readonly int kScalerDataTag = 0;
static Dictionary scalerInfos = new Dictionary();
///
/// ScalerInfo is a struct used to collect and send scaler info to the profile collectively.
///
[StructLayout(LayoutKind.Sequential)]
public unsafe struct ScalerInfo
{
///
/// The name of the scaler. 320 characters max.
///
public fixed byte scalerName[320];
///
/// If the scaler is currently enabled.
///
public uint enabled;
///
/// The override state of the scaler.
///
public int overrideLevel;
///
/// The current level of the scaler.
///
public int currentLevel;
///
/// The maximum level of the scaler.
///
public int maxLevel;
///
/// The actual scale of the scaler.
///
public float scale;
///
/// State if the scaler is currently applied.
///
public uint applied;
}
///
/// Adaptive Performance sends scaler data to the profiler each frame. It is collected from multiple places with this method and flushed once with .
///
/// The name of the scaler. 320 characters max.
/// If the scaler is currently enabled.
/// The override state of the scaler.
/// The current level of the scaler.
/// The actual scale of the scaler.
/// If the scaler is currently applied.
/// The maximum level of the scaler.
[Conditional("ENABLE_PROFILER")]
public static void EmitScalerDataToProfilerStream(string scalerName, bool enabled, int overrideLevel, int currentLevel, float scale, bool applied, int maxLevel)
{
if (!Profiler.enabled || scalerName.Length == 0)
return;
ScalerInfo scalerInfo;
bool existingInfo = scalerInfos.TryGetValue(scalerName, out scalerInfo);
if (!existingInfo)
scalerInfo = new ScalerInfo();
byte[] scalerNameBytes = Encoding.ASCII.GetBytes(scalerName);
scalerInfo.enabled = (uint)(enabled ? 1 : 0);
scalerInfo.overrideLevel = overrideLevel;
scalerInfo.currentLevel = currentLevel;
scalerInfo.scale = scale;
scalerInfo.maxLevel = maxLevel;
scalerInfo.applied = (uint)(applied ? 1 : 0);
unsafe
{
fixed(byte* pSource = scalerNameBytes)
{
UnsafeUtility.MemCpy(scalerInfo.scalerName, pSource, scalerNameBytes.Length);
}
}
if (!existingInfo)
scalerInfos.Add(scalerName, scalerInfo);
else
scalerInfos[scalerName] = scalerInfo;
}
///
/// Flushes the Adaptive Performance scaler data for this frame. Used in conjunction with .
///
public static void FlushScalerDataToProfilerStream()
{
ScalerInfo[] arr = new ScalerInfo[scalerInfos.Count];
scalerInfos.Values.CopyTo(arr, 0);
Profiler.EmitFrameMetaData(kAdaptivePerformanceProfilerModuleGuid, kScalerDataTag, arr);
}
}