using System; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; namespace UnityEngine.XR.ARSubsystems { /// /// Holds information related to an asynchronous camera image conversion request. Returned by /// . /// public struct XRAsyncCameraImageConversion : IDisposable, IEquatable { XRCameraSubsystem m_CameraSubsystem; int m_RequestId; #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle m_SafetyHandle; #endif /// /// The used during the conversion. /// /// /// The parameters used during the conversion. /// public XRCameraImageConversionParams conversionParams { get; private set; } /// /// The status of the request. /// /// /// The status of the request. /// public AsyncCameraImageConversionStatus status { get { if (m_CameraSubsystem == null) { return AsyncCameraImageConversionStatus.Disposed; } return m_CameraSubsystem.GetAsyncRequestStatus(m_RequestId); } } /// /// Start the image conversion using this class to interact with the asynchronous conversion and results. /// /// The camera subsystem performing the image conversion. /// The native handle for the camera image. /// The parameters for image conversion. internal XRAsyncCameraImageConversion(XRCameraSubsystem cameraSubsystem, int nativeHandle, XRCameraImageConversionParams conversionParams) { m_CameraSubsystem = cameraSubsystem; m_RequestId = m_CameraSubsystem.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 /// merely for access convenience. /// /// A new NativeArray representing the raw image data. This method may 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 != AsyncCameraImageConversionStatus.Ready) throw new InvalidOperationException("Async request is not ready."); IntPtr dataPtr; int dataLength; if (m_CameraSubsystem.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 Dispose. /// public void Dispose() { if (m_CameraSubsystem == null || m_RequestId == 0) return; m_CameraSubsystem.DisposeAsyncRequest(m_RequestId); m_CameraSubsystem = null; m_RequestId = 0; #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.Release(m_SafetyHandle); #endif } public override int GetHashCode() { unchecked { var hash = conversionParams.GetHashCode(); hash = hash * 486187739 + m_RequestId.GetHashCode(); if (m_CameraSubsystem != null) hash = hash * 486187739 + m_CameraSubsystem.GetHashCode(); return hash; } } public override bool Equals(object obj) { return ((obj is XRAsyncCameraImageConversion) && Equals((XRAsyncCameraImageConversion)obj)); } public bool Equals(XRAsyncCameraImageConversion other) { return (conversionParams.Equals(other.conversionParams)) && (m_RequestId == other.m_RequestId) && (m_CameraSubsystem == other.m_CameraSubsystem); } public static bool operator ==(XRAsyncCameraImageConversion lhs, XRAsyncCameraImageConversion rhs) { return lhs.Equals(rhs); } public static bool operator !=(XRAsyncCameraImageConversion lhs, XRAsyncCameraImageConversion rhs) { return !lhs.Equals(rhs); } public override string ToString() { return string.Format("ConversionParams: {0}", conversionParams); } } }