// SPDX-FileCopyrightText: 2023 Unity Technologies and the KTX for Unity authors // SPDX-License-Identifier: Apache-2.0 using System; using System.Runtime.InteropServices; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using UnityEngine; namespace KtxUnity { /// /// Wraps a managed byte[] in a NativeArray<byte>without copying memory. /// public class ManagedNativeArray : IDisposable { NativeArray m_NativeArray; GCHandle m_BufferHandle; #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle m_SafetyHandle; #endif bool m_Pinned; /// /// Wraps a managed byte[] in a NativeArray<byte>without copying memory. /// /// The original byte[] to convert into a NativeArray<byte> public unsafe ManagedNativeArray(byte[] original) { if (original != null) { m_BufferHandle = GCHandle.Alloc(original, GCHandleType.Pinned); fixed (void* bufferAddress = &original[0]) { m_NativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray(bufferAddress, original.Length, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS m_SafetyHandle = AtomicSafetyHandle.Create(); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(array: ref m_NativeArray, m_SafetyHandle); #endif } m_Pinned = true; } else { m_NativeArray = new NativeArray(); } } /// /// Points to the managed NativeArray<byte>. /// public NativeArray nativeArray => m_NativeArray; /// /// Disposes the managed NativeArray<byte>. /// public void Dispose() { if (m_Pinned) { #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.Release(m_SafetyHandle); #endif m_BufferHandle.Free(); } } } }