175 lines
6.4 KiB
C#
175 lines
6.4 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
using Unity.Collections;
|
|
using Unity.Collections.LowLevel.Unsafe;
|
|
using UnityEngine;
|
|
using UnityEngine.XR.OpenXR;
|
|
using UnityEngine.XR.OpenXR.Features;
|
|
|
|
#if UNITY_EDITOR
|
|
using UnityEditor.XR.OpenXR.Features;
|
|
#endif
|
|
|
|
namespace Unity.XR.OpenXR.Features.PICOSupport
|
|
{
|
|
public enum SystemDisplayFrequency
|
|
{
|
|
Default,
|
|
RefreshRate72=72,
|
|
RefreshRate90=90,
|
|
RefreshRate120=120,
|
|
}
|
|
#if UNITY_EDITOR
|
|
[OpenXRFeature(UiName = "OpenXR Display Refresh Rate",
|
|
Hidden = false,
|
|
BuildTargetGroups = new[] { UnityEditor.BuildTargetGroup.Android },
|
|
Company = "PICO",
|
|
OpenxrExtensionStrings = extensionString,
|
|
Version = "1.0.0",
|
|
FeatureId = featureId)]
|
|
#endif
|
|
public class DisplayRefreshRateFeature : OpenXRFeatureBase
|
|
{
|
|
public const string featureId = "com.pico.openxr.feature.refreshrate";
|
|
public const string extensionString = "XR_FB_display_refresh_rate";
|
|
public static bool isExtensionEnable =false;
|
|
public override void Initialize(IntPtr intPtr)
|
|
{
|
|
isExtensionEnable=_isExtensionEnable;
|
|
initialize(intPtr, xrInstance);
|
|
}
|
|
public override string GetExtensionString()
|
|
{
|
|
return extensionString;
|
|
}
|
|
|
|
public override void SessionCreate()
|
|
{
|
|
PICOProjectSetting projectConfig = PICOProjectSetting.GetProjectConfig();
|
|
if (projectConfig.displayFrequency != SystemDisplayFrequency.Default)
|
|
{
|
|
float displayRefreshRate = 0;
|
|
GetDisplayRefreshRate(ref displayRefreshRate);
|
|
PLog.i($"GetDisplayRefreshRate:{displayRefreshRate}");
|
|
SetDisplayRefreshRate(projectConfig.displayFrequency);
|
|
}
|
|
}
|
|
public static bool SetDisplayRefreshRate(SystemDisplayFrequency DisplayFrequency)
|
|
{
|
|
if (!isExtensionEnable)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
PLog.i($"SetDisplayRefreshRate:{DisplayFrequency}");
|
|
float rate = 0;
|
|
switch (DisplayFrequency)
|
|
{
|
|
case SystemDisplayFrequency.Default:
|
|
return true;
|
|
case SystemDisplayFrequency.RefreshRate72:
|
|
rate = 72;
|
|
break;
|
|
case SystemDisplayFrequency.RefreshRate90:
|
|
rate = 90;
|
|
break;
|
|
case SystemDisplayFrequency.RefreshRate120:
|
|
rate = 120;
|
|
break;
|
|
}
|
|
|
|
return SetDisplayRefreshRate(rate);
|
|
}
|
|
|
|
public static bool GetDisplayRefreshRate(ref float displayRefreshRate)
|
|
{
|
|
if (!isExtensionEnable)
|
|
{
|
|
return false;
|
|
}
|
|
return xrGetDisplayRefreshRateFB(
|
|
xrSession, ref displayRefreshRate);
|
|
}
|
|
|
|
private static bool SetDisplayRefreshRate(float displayRefreshRate)
|
|
{
|
|
if (!isExtensionEnable)
|
|
{
|
|
return false;
|
|
}
|
|
return xrRequestDisplayRefreshRateFB(
|
|
xrSession, displayRefreshRate);
|
|
}
|
|
|
|
private static bool EnumerateDisplayRefreshRates(uint displayRefreshRateCapacityInput,
|
|
ref uint displayRefreshRateCountOutput, ref float displayRefreshRates)
|
|
{
|
|
if (!isExtensionEnable)
|
|
{
|
|
return false;
|
|
}
|
|
return xrEnumerateDisplayRefreshRatesFB(
|
|
xrSession, displayRefreshRateCapacityInput, ref displayRefreshRateCountOutput, ref displayRefreshRates);
|
|
}
|
|
|
|
public static int GetDisplayRefreshRateCount()
|
|
{
|
|
if (!isExtensionEnable)
|
|
{
|
|
return 0;
|
|
}
|
|
return xrGetDisplayRefreshRateCount(xrSession);
|
|
}
|
|
|
|
public static bool TryGetSupportedDisplayRefreshRates(
|
|
Allocator allocator, out NativeArray<float> refreshRates)
|
|
{
|
|
refreshRates = default;
|
|
|
|
if (!isExtensionEnable)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var numDisplayRefreshRates = xrGetDisplayRefreshRateCount(xrSession);
|
|
if (numDisplayRefreshRates == 0)
|
|
{
|
|
Debug.LogError($"{nameof(TryGetSupportedDisplayRefreshRates)} failed due to an unknown error.");
|
|
return false;
|
|
}
|
|
|
|
unsafe
|
|
{
|
|
refreshRates = new NativeArray<float>(numDisplayRefreshRates, allocator);
|
|
if (!refreshRates.IsCreated)
|
|
return false;
|
|
|
|
return TryGetDisplayRefreshRates(xrSession,
|
|
NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(refreshRates),
|
|
(uint)numDisplayRefreshRates);
|
|
}
|
|
}
|
|
|
|
private const string ExtLib = "openxr_pico";
|
|
|
|
[DllImport(ExtLib, EntryPoint = "PICO_initialize_DisplayRefreshRates", CallingConvention = CallingConvention.Cdecl)]
|
|
private static extern void initialize(IntPtr xrGetInstanceProcAddr, ulong xrInstance);
|
|
|
|
[DllImport(ExtLib, EntryPoint = "PICO_xrEnumerateDisplayRefreshRatesFB", CallingConvention = CallingConvention.Cdecl)]
|
|
private static extern bool xrEnumerateDisplayRefreshRatesFB(ulong xrSession,
|
|
uint displayRefreshRateCapacityInput, ref uint displayRefreshRateCountOutput,
|
|
ref float displayRefreshRates);
|
|
|
|
[DllImport(ExtLib, EntryPoint = "PICO_xrGetDisplayRefreshRateFB", CallingConvention = CallingConvention.Cdecl)]
|
|
private static extern bool xrGetDisplayRefreshRateFB(ulong xrSession, ref float displayRefreshRate);
|
|
|
|
[DllImport(ExtLib, EntryPoint = "PICO_xrRequestDisplayRefreshRateFB", CallingConvention = CallingConvention.Cdecl)]
|
|
private static extern bool xrRequestDisplayRefreshRateFB(ulong xrSession, float displayRefreshRate);
|
|
[DllImport(ExtLib, EntryPoint = "PICO_xrGetDisplayRefreshRateCount", CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern int xrGetDisplayRefreshRateCount(ulong xrSession);
|
|
|
|
[DllImport(ExtLib, EntryPoint = "PICO_xrTryGetDisplayRefreshRates", CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern unsafe bool TryGetDisplayRefreshRates(ulong xrSession,void* refreshRates, uint capacity);
|
|
}
|
|
} |