using Ryujinx.Audio.Renderer.Utils; using Ryujinx.Common; using System; using System.Diagnostics; using System.Runtime.CompilerServices; namespace Ryujinx.Audio.Renderer.Common { public class WorkBufferAllocator { public Memory BackingMemory { get; } public ulong Offset { get; private set; } public WorkBufferAllocator(Memory backingMemory) { BackingMemory = backingMemory; } public Memory Allocate(ulong size, int align) { Debug.Assert(align != 0); if (size != 0) { ulong alignedOffset = BitUtils.AlignUp(Offset, (ulong)align); if (alignedOffset + size <= (ulong)BackingMemory.Length) { Memory result = BackingMemory.Slice((int)alignedOffset, (int)size); Offset = alignedOffset + size; // Clear the memory to be sure that is does not contain any garbage. result.Span.Fill(0); return result; } } return Memory.Empty; } public Memory Allocate(ulong count, int align) where T : unmanaged { Memory allocatedMemory = Allocate((ulong)Unsafe.SizeOf() * count, align); if (allocatedMemory.IsEmpty) { return Memory.Empty; } return SpanMemoryManager.Cast(allocatedMemory); } public static ulong GetTargetSize(ulong currentSize, ulong count, int align) where T : unmanaged { return BitUtils.AlignUp(currentSize, (ulong)align) + (ulong)Unsafe.SizeOf() * count; } } }