Files
adriadri6972 d3d9c5f833 upload project
2025-07-31 15:21:08 +02:00

88 lines
3.9 KiB
C#

using System;
using System.Runtime.InteropServices;
using AOT;
using UnityEngine.XR.ARSubsystems;
namespace UnityEngine.XR.ARKit
{
/// <summary>
/// Represents an asynchronous promise of a high-resolution CPU image.
/// </summary>
public class HighResolutionCpuImagePromise : Promise<HighResolutionCpuImagePromise.Result>
{
/// <summary>
/// The instance currently awaiting a result, or <see langword="null"/> if no instance currently awaits a result.
/// </summary>
/// <remarks>
/// <para>IL2CPP cannot currently marshal instance methods, therefore the callback function passed to the
/// native API must be static. In order to call the instance method <see cref="Promise{T}.Resolve"/> from within
/// the callback, this class must keep a static reference to the instance that will be resolved by the callback.</para>
/// <para>This design has a limitation that only one promise instance at a time can await a result; however, the
/// native ARKit API for high resolution frame capture has the same limitation, so there is no net negative impact.</para>
/// <para>Refer to ARKit's <a href="https://developer.apple.com/documentation/arkit/arsession/3975720-capturehighresolutionframewithco?language=objc">
/// captureHighResolutionFrameWithCompletion</a> documentation for more information.</para>
/// </remarks>
static HighResolutionCpuImagePromise s_Instance;
/// <summary>
/// The <see cref="XRCpuImage.Cinfo"/> object whose fields will be assigned by the native API.
/// </summary>
static XRCpuImage.Cinfo s_Cinfo;
/// <summary>
/// The function pointer for <see cref="OnPromiseComplete"/> to be marshalled to native API.
/// </summary>
static IntPtr s_OnPromiseCompleteFuncPtr = Marshal.GetFunctionPointerForDelegate((HighResolutionCpuImageCallback)OnPromiseComplete);
/// <summary>
/// Callback passed to the native API to call when the high resolution frame capture is complete.
/// </summary>
delegate void HighResolutionCpuImageCallback(bool wasSuccessful);
internal HighResolutionCpuImagePromise()
{
if (s_Instance != null)
{
Debug.LogError("A previous request for a high resolution capture hasn't completed yet. Subsequent requests will fail until the request in progress is completed.");
Resolve(default);
return;
}
s_Instance = this;
ARKitCameraSubsystem.TryAcquireHighResolutionCpuImageNative(s_OnPromiseCompleteFuncPtr, out s_Cinfo);
}
[MonoPInvokeCallback(typeof(HighResolutionCpuImageCallback))]
static void OnPromiseComplete(bool wasSuccessful)
{
var result = new Result
{
wasSuccessful = wasSuccessful,
highResolutionCpuImage = wasSuccessful ? new XRCpuImage(ARKitCpuImageApi.instance, s_Cinfo) : default
};
s_Instance.Resolve(result);
s_Instance = null;
}
/// <summary>
/// Represents the result of an asynchronous request for a high resolution CPU image.
/// </summary>
public struct Result
{
/// <summary>
/// If <see langword="true"/>, <see cref="highResolutionCpuImage"/> is initialized with a valid CPU image.
/// If <see langword="false"/>, <see cref="highResolutionCpuImage"/> has a default value.
/// </summary>
public bool wasSuccessful;
/// <summary>
/// The high resolution CPU image. You are responsible to <see cref="XRCpuImage.Dispose"/> this image if
/// <see cref="wasSuccessful"/> is <see langword="true"/>.
/// </summary>
/// <seealso cref="wasSuccessful"/>
public XRCpuImage highResolutionCpuImage;
}
}
}