// // Copyright (c) 2019-2021 Ryujinx // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . // 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, 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, align) + (ulong)Unsafe.SizeOf() * count; } } }