XR SDK 统计接口用于注册和管理统计数据。XR一个涵盖虚拟现实 (VR)、增强现实 (AR) 和混合现实 (MR) 应用程序的总称。支持这些形式的交互式应用程序的设备可以称为 XR 设备。更多信息
参见 术语表
使用 XR 统计接口在各个子系统之间记录统计数据。唯一支持的统计原始数据类型是浮点数。
使用 UnityPluginLoad
入口点方法获取指向 XRStats 接口的指针
IUnityXRStats* sXRStats = nullptr;
extern "C" void UNITY_INTERFACE_EXPORT UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
sXRStats = (IUnityXRStats*)unityInterfaces->GetInterface(UNITY_GET_INTERFACE_GUID(IUnityXRStats));
//...
}
使用统计接口注册您的子系统和各个统计数据定义
static UnityXRStatId m_GPUFrameTimeID;
static UnityXRStatId m_DroppedFrameCountID;
static UnityXRStatId m_WorkThreadStat;
static UnitySubsystemErrorCode ExampleDisplayProvider_Start(UnitySubsystemHandle handle)
{
if (sXRStats)
{
sXRStats->RegisterStatSource(handle);
m_GPUFrameTimeID = sXRStats->RegisterStatDefinition(handle, "Example.GPUTime", kUnityXRStatOptionNone);
m_DroppedFrameCountID = sXRStats->RegisterStatDefinition(handle, "Example.DroppedFrame", kUnityXRStatOptionNone);
m_WorkThreadStat = sXRStats->RegisterStatDefinition(handle, "Example.WorkerThreadStat", kUnityXRStatOptionNone);
}
return kUnitySubsystemErrorCodeSuccess;
}
在 Gfx 线程上更新统计数据
extern float GetLastGPUTime(); //provided by your runtime
static void ExampleDisplayProvider_GfxThreadCall(UnitySubsystemHandle handle)
{
sXRStats->SetStatFloat(m_GPUFrameTimeID, GetLastGPUTime());
// Do gfx thread things
}
在主线程上更新统计数据
extern float GetDroppedFrameCount(); //provided by your runtime
static void ExampleDisplayProvider_MainThreadCall(UnitySubsystemHandle handle)
{
sXRStats->SetStatFloat(m_DroppedFrameCountID, GetDroppedFrameCount());
// Do main thread things
}
在您自己的线程上更新统计数据,但请务必调用 IncrementStatFrame
以使该线程的当前帧与其他线程保持同步(主线程和图形线程内部会管理此操作)
extern float GetWorkerThreadStat(); //provided by your runtime
static void ExampleDisplayProvider_MyWorkerThread(UnitySubsystemHandle handle)
{
sXRStats->IncrementStatFrame();
sXRStats->SetStatFloat(m_WorkThreadStat, GetWorkerThreadStat());
// Do worker thread things
}
子系统停止时取消注册统计数据源
static void ExampleDisplayProvider_Stop(UnitySubsystemHandle handle)
{
sXRStats->UnregisterStatSource(handle);
}
通过 SetStatFloat
更新统计数据是线程安全的。但是,注册和取消注册统计数据源不是线程安全的,只能在统计数据源生命周期的 Start 和 Stop 函数期间的主线程上执行。
处理统计数据的队列大小为 2000。此队列在所有线程和所有子系统之间共享,并且仅在帧完成时进行服务。因此,您应尽量减少对 SetStatFloat
的调用次数,以避免填满队列。
注意:队列已满时记录的任何统计数据都将丢失。
在 UnityEngine.XR.Provider
命名空间中,使用 public static bool TryGetStat(Experimental.IntegratedSubsystem xrSubsystem, string tag, out float value)
获取已注册并使用您的提供程序更新的统计数据
using UnityEngine.XR.Provider;
using System.Collections.Generic;
using UnityEngine.Experimental.XR;
using UnityEngine.Experimental;
using UnityEngine;
public static class ExampleProviderStats
{
public static float GPUFrameTime()
{
float tmp;
XRStats.TryGetStat(GetFirstDisplaySubsystem(), "Example.GPUTime", out tmp);
return tmp;
}
public static int DroppedFrameCount()
{
float tmp;
XRStats.TryGetStat(GetFirstDisplaySubsystem(), "Example.DroppedFrame", out tmp);
return (int)tmp;
}
public static float MyWorkerThreadStat()
{
float tmp;
XRStats.TryGetStat(GetFirstDisplaySubsystem(), "Example.WorkerThreadStat", out tmp);
return tmp;
}
// etc...
private static IntegratedSubsystem GetFirstDisplaySubsystem()
{
List<XRDisplaySubsystem> displays = new List<XRDisplaySubsystem>();
SubsystemManager.GetInstances(displays);
if (displays.Count == 0)
{
Debug.Log("No display subsystem found.");
return null;
}
return displays[0];
}
}
编写如上例所示的公共访问器方法可以帮助用户获取统计数据,而无需筛选提供程序文档并查找已注册统计数据的子系统。
此外,某些子系统具有预定义的统计数据标签。您的提供程序可以通过注册特定于子系统的统计数据标签(例如:Headers/XR/UnityXRDisplayStats.h
)来为 Unity 公开的预定义统计数据 API提供统计数据。