// Copyright HTC Corporation All Rights Reserved. using System.Runtime.InteropServices; using System; using AOT; using UnityEngine.Profiling; namespace VIVE.OpenXR { partial class ViveInterceptors { public struct XrCompositionLayerBaseHeader { public XrStructureType type; // This base structure itself has no associated XrStructureType value. public System.IntPtr next; public XrCompositionLayerFlags layerFlags; public XrSpace space; } public struct XrFrameEndInfo { public XrStructureType type; public System.IntPtr next; public XrTime displayTime; public XrEnvironmentBlendMode environmentBlendMode; public uint layerCount; public IntPtr layers; // XrCompositionLayerBaseHeader IntPtr array } public delegate XrResult DelegateXrEndFrame(XrSession session, ref XrFrameEndInfo frameEndInfo); private static readonly DelegateXrEndFrame xrEndFrameInterceptorHandle = new DelegateXrEndFrame(XrEndFrameInterceptor); private static readonly IntPtr xrEndFrameInterceptorPtr = Marshal.GetFunctionPointerForDelegate(xrEndFrameInterceptorHandle); static DelegateXrEndFrame XrEndFrameOriginal = null; [MonoPInvokeCallback(typeof(DelegateXrEndFrame))] private static XrResult XrEndFrameInterceptor(XrSession session, ref XrFrameEndInfo frameEndInfo) { // instance must not null //if (instance == null) // return XrEndFrameOriginal(session, ref frameEndInfo); Profiler.BeginSample("VI:EndFrame"); XrResult result = XrResult.XR_SUCCESS; if (instance.BeforeOriginalEndFrame != null && !instance.BeforeOriginalEndFrame(session, ref frameEndInfo, ref result)) { Profiler.EndSample(); return result; } result = XrEndFrameOriginal(session, ref frameEndInfo); instance.AfterOriginalEndFrame?.Invoke(session, ref frameEndInfo, ref result); Profiler.EndSample(); return result; } /// /// If you return false, the original function will not be called. /// /// /// /// /// public delegate bool DelegateXrEndFrameInterceptor(XrSession session, ref XrFrameEndInfo frameEndInfo, ref XrResult result); /// /// Use this to intercept the original function. This will be called before the original function. /// public DelegateXrEndFrameInterceptor BeforeOriginalEndFrame; /// /// Use this to intercept the original function. This will be called after the original function. /// public DelegateXrEndFrameInterceptor AfterOriginalEndFrame; #if PERFORMANCE_TEST public delegate XrResult DelegateXrLocateSpace(XrSpace space, XrSpace baseSpace, XrTime time, ref XrSpaceLocation location); private static readonly DelegateXrLocateSpace xrLocateSpaceInterceptorHandle = new DelegateXrLocateSpace(XrLocateSpaceInterceptor); private static readonly IntPtr xrLocateSpaceInterceptorPtr = Marshal.GetFunctionPointerForDelegate(xrLocateSpaceInterceptorHandle); static DelegateXrLocateSpace XrLocateSpaceOriginal = null; [MonoPInvokeCallback(typeof(DelegateXrLocateSpace))] public static XrResult XrLocateSpaceInterceptor(XrSpace space, XrSpace baseSpace, XrTime time, ref XrSpaceLocation location) { Profiler.BeginSample("VI:LocateSpace"); var ret = XrLocateSpaceOriginal(space, baseSpace, time, ref location); Profiler.EndSample(); return ret; } #endif } }