aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger
diff options
context:
space:
mode:
authorjhorv <38920027+jhorv@users.noreply.github.com>2024-04-21 06:57:35 -0400
committerGitHub <noreply@github.com>2024-04-21 12:57:35 +0200
commit216026c096d844f8bf09ee0e185dec4111c64095 (patch)
tree222eb5476aacb79f9d67abd799ee1657c2d63e7c /src/Ryujinx.HLE/HOS/Services/SurfaceFlinger
parent7070cf6ae502b5c11551fceb164bc9f158ba980b (diff)
Use pooled memory and avoid memory copies (#6691)
* perf: use ByteMemoryPool * feat: KPageTableBase/KPageTable new methods to read and write `ReadOnlySequence<byte>` * new: add IWritableBlock.Write(ulong, ReadOnlySequence<byte>) with default impl * perf: use GetReadOnlySequence() instead of GetSpan() * perf: make `Parcel` IDisposable, use `ByteMemoryPool` for internal allocation, and make Parcel consumers dispose of it * remove comment about copySize * remove unnecessary Clear()
Diffstat (limited to 'src/Ryujinx.HLE/HOS/Services/SurfaceFlinger')
-rw-r--r--src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IBinder.cs4
-rw-r--r--src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Parcel.cs32
2 files changed, 26 insertions, 10 deletions
diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IBinder.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IBinder.cs
index 0fb2dfd2..54aac48a 100644
--- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IBinder.cs
+++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IBinder.cs
@@ -13,10 +13,10 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
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?
- 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();
diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Parcel.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Parcel.cs
index 4ac0525b..c6cd60d0 100644
--- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Parcel.cs
+++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Parcel.cs
@@ -1,7 +1,9 @@
using Ryujinx.Common;
+using Ryujinx.Common.Memory;
using Ryujinx.Common.Utilities;
using Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types;
using System;
+using System.Buffers;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -9,13 +11,13 @@ using System.Text;
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);
@@ -24,9 +26,11 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
private int _payloadPosition;
private int _objectPosition;
- public Parcel(byte[] rawData)
+ private bool _isDisposed;
+
+ public Parcel(ReadOnlySpan<byte> data)
{
- _rawData = rawData;
+ _rawDataOwner = ByteMemoryPool.RentCopy(data);
_payloadPosition = 0;
_objectPosition = 0;
@@ -36,7 +40,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
{
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.ObjectsSize = objectsSize;
@@ -132,7 +136,9 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
// TODO: figure out what this value is
- WriteInplaceObject(new byte[4] { 0, 0, 0, 0 });
+ Span<byte> fourBytes = stackalloc byte[4];
+
+ WriteInplaceObject(fourBytes);
}
public AndroidStrongPointer<T> ReadStrongPointer<T>() where T : unmanaged, IFlattenable
@@ -219,5 +225,15 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
return Raw[..(int)(Header.PayloadSize + Header.ObjectsSize + Unsafe.SizeOf<ParcelHeader>())];
}
+
+ public void Dispose()
+ {
+ if (!_isDisposed)
+ {
+ _isDisposed = true;
+
+ _rawDataOwner.Dispose();
+ }
+ }
}
}