using System; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; namespace UnityEngine.XR.ARSubsystems { public partial struct XRCpuImage { /// /// Holds information related to an asynchronous camera image conversion request. Returned by /// . /// public struct AsyncConversion : IDisposable, IEquatable { XRCpuImage.Api m_Api; int m_RequestId; #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle m_SafetyHandle; #endif /// /// The used during the conversion. /// /// /// The parameters used during the conversion. /// public ConversionParams conversionParams { get; private set; } /// /// The status of the request. /// /// /// The status of the request. /// public AsyncConversionStatus status => m_Api?.GetAsyncRequestStatus(m_RequestId) ?? AsyncConversionStatus.Disposed; /// /// Start the image conversion using this class to interact with the asynchronous conversion and results. /// /// The CPU image API performing the image conversion. /// The native handle for the camera image. /// The parameters for image conversion. internal AsyncConversion(XRCpuImage.Api api, int nativeHandle, ConversionParams conversionParams) { m_Api = api; m_RequestId = m_Api.ConvertAsync(nativeHandle, conversionParams); this.conversionParams = conversionParams; #if ENABLE_UNITY_COLLECTIONS_CHECKS m_SafetyHandle = AtomicSafetyHandle.Create(); #endif } /// /// Get the raw image data. The returned NativeArray is a direct view into the native memory. The /// memory is only valid until this is disposed. /// /// The type of data to return. No conversion is performed based on the type; this is /// only for access convenience. /// /// A new NativeArray representing the raw image data. This method might fail; use /// NativeArray.IsCreated to determine the validity of the data. /// /// Thrown if the asynchronous conversion /// is not or if the conversion is /// invalid. public unsafe NativeArray GetData() where T : struct { if (status != AsyncConversionStatus.Ready) throw new InvalidOperationException("Async request is not ready."); IntPtr dataPtr; int dataLength; if (m_Api.TryGetAsyncRequestData(m_RequestId, out dataPtr, out dataLength)) { int stride = UnsafeUtility.SizeOf(); var array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray( (void*)dataPtr, dataLength / stride, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, m_SafetyHandle); #endif return array; } throw new InvalidOperationException("The XRAsyncCameraImageConversion is not valid."); } /// /// Dispose native resources associated with this request, including the raw image data. The `NativeArray` /// returned by is invalidated immediately after calling . /// public void Dispose() { if (m_Api == null || m_RequestId == 0) return; m_Api.DisposeAsyncRequest(m_RequestId); m_Api = null; m_RequestId = 0; #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.Release(m_SafetyHandle); #endif } /// /// Generates a hash suitable for use with containers like `HashSet` and `Dictionary`. /// /// A hash code generated from this object's fields. public override int GetHashCode() => HashCodeUtil.Combine( conversionParams.GetHashCode(), m_RequestId.GetHashCode(), HashCodeUtil.ReferenceHash(m_Api)); /// /// Tests for equality. /// /// The `object` to compare against. /// `True` if is of type and /// also returns `true`; otherwise `false`. public override bool Equals(object obj) { return ((obj is AsyncConversion) && Equals((AsyncConversion)obj)); } /// /// Tests for equality. /// /// The other to compare against. /// `True` if every field in is equal to this , otherwise false. public bool Equals(AsyncConversion other) { return (conversionParams.Equals(other.conversionParams)) && (m_RequestId == other.m_RequestId) && (m_Api == other.m_Api); } /// /// Tests for equality. Same as . /// /// The to compare with . /// The to compare with . /// `True` if is equal to , otherwise `false`. public static bool operator ==(AsyncConversion lhs, AsyncConversion rhs) => lhs.Equals(rhs); /// /// Tests for inequality. Same as `!`. /// /// The to compare with . /// The to compare with . /// `True` if is not equal to , otherwise `false`. public static bool operator !=(AsyncConversion lhs, AsyncConversion rhs) => !lhs.Equals(rhs); /// /// Generates a string representation of this . /// /// A string representation of the conversion parameters. public override string ToString() => $"ConversionParams: {conversionParams}"; } } }