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