Unity XR SDK Stats 인터페이스 가이드

Unity의 XR SDK Stats 인터페이스는 통계 데이터를 등록하고 관리하는 데 사용됩니다. 이 문서는 XRStats 인터페이스를 사용하여 하위 시스템 간의 통계를 기록하는 방법에 대한 내용을 다루고 있습니다.

개요

XR Stats 인터페이스를 통해 부동 소수점 숫자인 통계를 기록할 수 있습니다. 통계에 대한 포인터는 UnityPluginLoad 메서드를 통해 얻을 수 있습니다.

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();
static void ExampleDisplayProvider_GfxThreadCall(UnitySubsystemHandle handle)
{
    sXRStats->SetStatFloat(m_GPUFrameTimeID, GetLastGPUTime());
    // Do gfx thread things
}

메인 스레드에서의 업데이트

extern float GetDroppedFrameCount();
static void ExampleDisplayProvider_MainThreadCall(UnitySubsystemHandle handle)
{
    sXRStats->SetStatFloat(m_DroppedFrameCountID, GetDroppedFrameCount());
    // Do main thread things
}

자체 스레드에서의 업데이트

자체 스레드에서 통계를 업데이트할 때는 IncrementStatFrame을 호출하여 해당 스레드의 현재 프레임을 다른 스레드와 동기화해야 합니다.

extern float GetWorkerThreadStat();
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 호출 횟수를 낮게 유지하여 대기열이 가득 차지 않도록 해야 합니다.

사용자에게 통계 표시

아래와 같이 TryGetStat 메서드를 사용하여 통계를 등록하고 업데이트할 수 있습니다.

using UnityEngine.XR.Provider;
using System.Collections.Generic;
using UnityEngine.Experimental.XR;
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];
    }
}

위 예제와 같은 공용 접근자 메서드를 작성하면 사용자가 공급자 문서를 참고하지 않고도 쉽게 통계를 얻을 수 있습니다.

이와 함께, 일부 하위 시스템에는 사전 정의된 통계 태그가 존재하며, 공급자는 Unity의 보조 시스템별 통계 태그를 등록하여 노출하는 사전 정의된 통계 API에 통계를 제공합니다.