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);
}
}
}