DisplayRefreshRateFeature.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using Unity.Collections;
  4. using Unity.Collections.LowLevel.Unsafe;
  5. using UnityEngine;
  6. using UnityEngine.XR.OpenXR;
  7. using UnityEngine.XR.OpenXR.Features;
  8. #if UNITY_EDITOR
  9. using UnityEditor.XR.OpenXR.Features;
  10. #endif
  11. namespace Unity.XR.OpenXR.Features.PICOSupport
  12. {
  13. public enum SystemDisplayFrequency
  14. {
  15. Default,
  16. RefreshRate72=72,
  17. RefreshRate90=90,
  18. RefreshRate120=120,
  19. }
  20. #if UNITY_EDITOR
  21. [OpenXRFeature(UiName = "OpenXR Display Refresh Rate",
  22. Hidden = false,
  23. BuildTargetGroups = new[] { UnityEditor.BuildTargetGroup.Android },
  24. Company = "PICO",
  25. OpenxrExtensionStrings = extensionString,
  26. Version = "1.0.0",
  27. FeatureId = featureId)]
  28. #endif
  29. public class DisplayRefreshRateFeature : OpenXRFeatureBase
  30. {
  31. public const string featureId = "com.pico.openxr.feature.refreshrate";
  32. public const string extensionString = "XR_FB_display_refresh_rate";
  33. public static bool isExtensionEnable =false;
  34. public override void Initialize(IntPtr intPtr)
  35. {
  36. isExtensionEnable=_isExtensionEnable;
  37. initialize(intPtr, xrInstance);
  38. }
  39. public override string GetExtensionString()
  40. {
  41. return extensionString;
  42. }
  43. public override void SessionCreate()
  44. {
  45. PICOProjectSetting projectConfig = PICOProjectSetting.GetProjectConfig();
  46. if (projectConfig.displayFrequency != SystemDisplayFrequency.Default)
  47. {
  48. float displayRefreshRate = 0;
  49. GetDisplayRefreshRate(ref displayRefreshRate);
  50. PLog.i($"GetDisplayRefreshRate:{displayRefreshRate}");
  51. SetDisplayRefreshRate(projectConfig.displayFrequency);
  52. }
  53. }
  54. public static bool SetDisplayRefreshRate(SystemDisplayFrequency DisplayFrequency)
  55. {
  56. if (!isExtensionEnable)
  57. {
  58. return false;
  59. }
  60. PLog.i($"SetDisplayRefreshRate:{DisplayFrequency}");
  61. float rate = 0;
  62. switch (DisplayFrequency)
  63. {
  64. case SystemDisplayFrequency.Default:
  65. return true;
  66. case SystemDisplayFrequency.RefreshRate72:
  67. rate = 72;
  68. break;
  69. case SystemDisplayFrequency.RefreshRate90:
  70. rate = 90;
  71. break;
  72. case SystemDisplayFrequency.RefreshRate120:
  73. rate = 120;
  74. break;
  75. }
  76. return SetDisplayRefreshRate(rate);
  77. }
  78. public static bool GetDisplayRefreshRate(ref float displayRefreshRate)
  79. {
  80. if (!isExtensionEnable)
  81. {
  82. return false;
  83. }
  84. return xrGetDisplayRefreshRateFB(
  85. xrSession, ref displayRefreshRate);
  86. }
  87. private static bool SetDisplayRefreshRate(float displayRefreshRate)
  88. {
  89. if (!isExtensionEnable)
  90. {
  91. return false;
  92. }
  93. return xrRequestDisplayRefreshRateFB(
  94. xrSession, displayRefreshRate);
  95. }
  96. private static bool EnumerateDisplayRefreshRates(uint displayRefreshRateCapacityInput,
  97. ref uint displayRefreshRateCountOutput, ref float displayRefreshRates)
  98. {
  99. if (!isExtensionEnable)
  100. {
  101. return false;
  102. }
  103. return xrEnumerateDisplayRefreshRatesFB(
  104. xrSession, displayRefreshRateCapacityInput, ref displayRefreshRateCountOutput, ref displayRefreshRates);
  105. }
  106. public static int GetDisplayRefreshRateCount()
  107. {
  108. if (!isExtensionEnable)
  109. {
  110. return 0;
  111. }
  112. return xrGetDisplayRefreshRateCount(xrSession);
  113. }
  114. public static bool TryGetSupportedDisplayRefreshRates(
  115. Allocator allocator, out NativeArray<float> refreshRates)
  116. {
  117. refreshRates = default;
  118. if (!isExtensionEnable)
  119. {
  120. return false;
  121. }
  122. var numDisplayRefreshRates = xrGetDisplayRefreshRateCount(xrSession);
  123. if (numDisplayRefreshRates == 0)
  124. {
  125. Debug.LogError($"{nameof(TryGetSupportedDisplayRefreshRates)} failed due to an unknown error.");
  126. return false;
  127. }
  128. unsafe
  129. {
  130. refreshRates = new NativeArray<float>(numDisplayRefreshRates, allocator);
  131. if (!refreshRates.IsCreated)
  132. return false;
  133. return TryGetDisplayRefreshRates(xrSession,
  134. NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(refreshRates),
  135. (uint)numDisplayRefreshRates);
  136. }
  137. }
  138. private const string ExtLib = "openxr_pico";
  139. [DllImport(ExtLib, EntryPoint = "PICO_initialize_DisplayRefreshRates", CallingConvention = CallingConvention.Cdecl)]
  140. private static extern void initialize(IntPtr xrGetInstanceProcAddr, ulong xrInstance);
  141. [DllImport(ExtLib, EntryPoint = "PICO_xrEnumerateDisplayRefreshRatesFB", CallingConvention = CallingConvention.Cdecl)]
  142. private static extern bool xrEnumerateDisplayRefreshRatesFB(ulong xrSession,
  143. uint displayRefreshRateCapacityInput, ref uint displayRefreshRateCountOutput,
  144. ref float displayRefreshRates);
  145. [DllImport(ExtLib, EntryPoint = "PICO_xrGetDisplayRefreshRateFB", CallingConvention = CallingConvention.Cdecl)]
  146. private static extern bool xrGetDisplayRefreshRateFB(ulong xrSession, ref float displayRefreshRate);
  147. [DllImport(ExtLib, EntryPoint = "PICO_xrRequestDisplayRefreshRateFB", CallingConvention = CallingConvention.Cdecl)]
  148. private static extern bool xrRequestDisplayRefreshRateFB(ulong xrSession, float displayRefreshRate);
  149. [DllImport(ExtLib, EntryPoint = "PICO_xrGetDisplayRefreshRateCount", CallingConvention = CallingConvention.Cdecl)]
  150. public static extern int xrGetDisplayRefreshRateCount(ulong xrSession);
  151. [DllImport(ExtLib, EntryPoint = "PICO_xrTryGetDisplayRefreshRates", CallingConvention = CallingConvention.Cdecl)]
  152. public static extern unsafe bool TryGetDisplayRefreshRates(ulong xrSession,void* refreshRates, uint capacity);
  153. }
  154. }