// Copyright HTC Corporation All Rights Reserved. #define DEBUG using AOT; using System; using System.Runtime.InteropServices; using UnityEngine.Profiling; using VIVE.OpenXR.FrameSynchronization; namespace VIVE.OpenXR { partial class ViveInterceptors { #region xrBeginSession public delegate XrResult xrBeginSessionDelegate(XrSession session, ref XrSessionBeginInfo beginInfo); private static xrBeginSessionDelegate xrBeginSessionOrigin = null; [MonoPInvokeCallback(typeof(xrBeginSessionDelegate))] private static XrResult xrBeginSessionInterceptor(XrSession session, ref XrSessionBeginInfo beginInfo) { Profiler.BeginSample("ViveInterceptors:BeginSession"); XrResult result = XrResult.XR_ERROR_FUNCTION_UNSUPPORTED; if (xrBeginSessionOrigin != null) { if (m_EnableFrameSynchronization) { frameSynchronizationSessionBeginInfo.mode = m_FrameSynchronizationMode; frameSynchronizationSessionBeginInfo.next = beginInfo.next; beginInfo.next = Marshal.AllocHGlobal(Marshal.SizeOf(frameSynchronizationSessionBeginInfo)); long offset = 0; if (IntPtr.Size == 4) offset = beginInfo.next.ToInt32(); else offset = beginInfo.next.ToInt64(); IntPtr frame_synchronization_session_begin_info_ptr = new IntPtr(offset); Marshal.StructureToPtr(frameSynchronizationSessionBeginInfo, frame_synchronization_session_begin_info_ptr, false); #if DEBUG if (IntPtr.Size == 4) offset = beginInfo.next.ToInt32(); else offset = beginInfo.next.ToInt64(); IntPtr fs_begin_info_ptr = new IntPtr(offset); XrFrameSynchronizationSessionBeginInfoHTC fsBeginInfo = (XrFrameSynchronizationSessionBeginInfoHTC)Marshal.PtrToStructure(fs_begin_info_ptr, typeof(XrFrameSynchronizationSessionBeginInfoHTC)); sb.Clear().Append("xrBeginSessionInterceptor() beginInfo.next = (").Append(fsBeginInfo.type).Append(", ").Append(fsBeginInfo.mode).Append(")"); DEBUG(sb); #endif } result = xrBeginSessionOrigin(session, ref beginInfo); } else { sb.Clear().Append("xrBeginSessionInterceptor() Not assign xrBeginSession!"); ERROR(sb); } Profiler.EndSample(); return result; } private static readonly xrBeginSessionDelegate xrBeginSession = new xrBeginSessionDelegate(xrBeginSessionInterceptor); private static readonly IntPtr xrBeginSessionPtr = Marshal.GetFunctionPointerForDelegate(xrBeginSession); #endregion private static XrFrameSynchronizationSessionBeginInfoHTC frameSynchronizationSessionBeginInfo = XrFrameSynchronizationSessionBeginInfoHTC.identity; private static bool m_EnableFrameSynchronization = false; private static XrFrameSynchronizationModeHTC m_FrameSynchronizationMode = XrFrameSynchronizationModeHTC.XR_FRAME_SYNCHRONIZATION_MODE_STABILIZED_HTC; /// /// Activate or deactivate the Frame Synchronization feature. /// /// True for activate /// The used for Frame Synchronization. public void ActivateFrameSynchronization(bool active, XrFrameSynchronizationModeHTC mode) { m_EnableFrameSynchronization = active; m_FrameSynchronizationMode = mode; sb.Clear().Append("ActivateFrameSynchronization() ").Append(active ? "enable " : "disable ").Append(mode); DEBUG(sb); } } }