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));
//...
}
サブシステムや個々の統計定義を Stats インターフェースに登録します。
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());
// gfx スレッドの作業
}
メインスレッドの統計情報を更新します。
extern float GetDroppedFrameCount(); //ランタイムによって提供されます
static void ExampleDisplayProvider_MainThreadCall(UnitySubsystemHandle handle)
{
sXRStats->SetStatFloat(m_DroppedFrameCountID, GetDroppedFrameCount());
// メインスレッドの作業
}
自身のスレッドで統計情報を更新し、必ず IncrementStatFrame
を呼び出して、そのスレッドの現在のフレームを他のスレッドと同期させてください (これはメインスレッドとグラフィックススレッドで内部的に管理されます)。
extern float GetWorkerThreadStat(); //ランタイムによって提供されます
static void ExampleDisplayProvider_MyWorkerThread(UnitySubsystemHandle handle)
{
sXRStats->IncrementStatFrame();
sXRStats->SetStatFloat(m_WorkThreadStat, GetWorkerThreadStat());
// ワーカースレッドの作業
}
サブシステムの停止時に統計ソースの登録を解除します。
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;
}
// その他...
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 の統計データを提供することができます