XR SDK Stats 인터페이스는 통계 데이터를 등록하고 관리하는 데 사용됩니다.
XR Stats 인터페이스를 사용하여 다양한 하위 시스템 간의 통계를 기록합니다. 지원되는 유일한 통계 프리미티브는 부동 소수점 숫자입니다.
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
를 통한 통계 업데이트는 스레드에 안전합니다. 하지만 통계 소스의 등록 및 등록 해제는 스레드에 안전하지 않으며, 통계 소스 라이프사이클의 시작 및 중지 기능 동안에만 메인 스레드에서 작업이 이루어져야 합니다.
통계 처리를 위한 대기열 크기는 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];
}
}
위 예제와 같은 공용 접근자 메서드를 작성하면 사용자들이 공급자 문서를 살펴보거나 통계가 등록된 하위 시스템을 찾지 않고도 통계를 손쉽게 얻을 수 있습니다.
또한 일부 하위 시스템에는 사전 정의된 통계 태그가 있습니다. 공급자는 Unity가 보조 시스템별 통계 태그를 등록하여 노출하는 사전 정의된 통계 API에 대한 통계를 제공할 수 있습니다(예: Headers/XR/UnityXRDisplayStats.h
).