perf: make Parcel IDisposable, use ByteMemoryPool for internal allocation, and make Parcel consumers dispose of it

This commit is contained in:
jhorv 2024-04-13 13:19:28 -04:00
commit cf3b9d6568
3 changed files with 29 additions and 12 deletions

View file

@ -13,10 +13,10 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
ResultCode OnTransact(uint code, uint flags, ReadOnlySpan<byte> inputParcel, Span<byte> outputParcel) ResultCode OnTransact(uint code, uint flags, ReadOnlySpan<byte> inputParcel, Span<byte> outputParcel)
{ {
Parcel inputParcelReader = new(inputParcel.ToArray()); using Parcel inputParcelReader = new(inputParcel);
// TODO: support objects? // TODO: support objects?
Parcel outputParcelWriter = new((uint)(outputParcel.Length - Unsafe.SizeOf<ParcelHeader>()), 0); using Parcel outputParcelWriter = new((uint)(outputParcel.Length - Unsafe.SizeOf<ParcelHeader>()), 0);
string inputInterfaceToken = inputParcelReader.ReadInterfaceToken(); string inputInterfaceToken = inputParcelReader.ReadInterfaceToken();

View file

@ -1,7 +1,9 @@
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Memory;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types; using Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types;
using System; using System;
using System.Buffers;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -9,13 +11,13 @@ using System.Text;
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
{ {
class Parcel sealed class Parcel : IDisposable
{ {
private readonly byte[] _rawData; private readonly IMemoryOwner<byte> _rawDataOwner;
private Span<byte> Raw => new(_rawData); private Span<byte> Raw => _rawDataOwner.Memory.Span;
private ref ParcelHeader Header => ref MemoryMarshal.Cast<byte, ParcelHeader>(_rawData)[0]; private ref ParcelHeader Header => ref MemoryMarshal.Cast<byte, ParcelHeader>(Raw)[0];
private Span<byte> Payload => Raw.Slice((int)Header.PayloadOffset, (int)Header.PayloadSize); private Span<byte> Payload => Raw.Slice((int)Header.PayloadOffset, (int)Header.PayloadSize);
@ -24,9 +26,11 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
private int _payloadPosition; private int _payloadPosition;
private int _objectPosition; private int _objectPosition;
public Parcel(byte[] rawData) private bool _isDisposed;
public Parcel(ReadOnlySpan<byte> data)
{ {
_rawData = rawData; _rawDataOwner = ByteMemoryPool.RentCopy(data);
_payloadPosition = 0; _payloadPosition = 0;
_objectPosition = 0; _objectPosition = 0;
@ -36,7 +40,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
{ {
uint headerSize = (uint)Unsafe.SizeOf<ParcelHeader>(); uint headerSize = (uint)Unsafe.SizeOf<ParcelHeader>();
_rawData = new byte[BitUtils.AlignUp<uint>(headerSize + payloadSize + objectsSize, 4)]; _rawDataOwner = ByteMemoryPool.RentCleared(BitUtils.AlignUp<uint>(headerSize + payloadSize + objectsSize, 4));
Header.PayloadSize = payloadSize; Header.PayloadSize = payloadSize;
Header.ObjectsSize = objectsSize; Header.ObjectsSize = objectsSize;
@ -132,7 +136,10 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
// TODO: figure out what this value is // TODO: figure out what this value is
WriteInplaceObject(new byte[4] { 0, 0, 0, 0 }); Span<byte> fourBytes = stackalloc byte[4];
fourBytes.Clear();
WriteInplaceObject(fourBytes);
} }
public AndroidStrongPointer<T> ReadStrongPointer<T>() where T : unmanaged, IFlattenable public AndroidStrongPointer<T> ReadStrongPointer<T>() where T : unmanaged, IFlattenable
@ -219,5 +226,15 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
return Raw[..(int)(Header.PayloadSize + Header.ObjectsSize + Unsafe.SizeOf<ParcelHeader>())]; return Raw[..(int)(Header.PayloadSize + Header.ObjectsSize + Unsafe.SizeOf<ParcelHeader>())];
} }
public void Dispose()
{
if (!_isDisposed)
{
_isDisposed = true;
_rawDataOwner.Dispose();
}
}
} }
} }

View file

@ -250,7 +250,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
context.Device.System.SurfaceFlinger.SetRenderLayer(layerId); context.Device.System.SurfaceFlinger.SetRenderLayer(layerId);
Parcel parcel = new(0x28, 0x4); using Parcel parcel = new(0x28, 0x4);
parcel.WriteObject(producer, "dispdrv\0"); parcel.WriteObject(producer, "dispdrv\0");
@ -288,7 +288,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
context.Device.System.SurfaceFlinger.SetRenderLayer(layerId); context.Device.System.SurfaceFlinger.SetRenderLayer(layerId);
Parcel parcel = new(0x28, 0x4); using Parcel parcel = new(0x28, 0x4);
parcel.WriteObject(producer, "dispdrv\0"); parcel.WriteObject(producer, "dispdrv\0");