perf: make Parcel
IDisposable, use ByteMemoryPool
for internal allocation, and make Parcel consumers dispose of it
This commit is contained in:
parent
32e5d59107
commit
cf3b9d6568
3 changed files with 29 additions and 12 deletions
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue