aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Services/SurfaceFlinger
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2020-12-01 20:23:43 -0300
committerGitHub <noreply@github.com>2020-12-02 00:23:43 +0100
commitcf6cd714884c41e9550757e364c2f4f5b04fc7f3 (patch)
treebea748b4d1a350e5b8075d63ec9d39d49693829d /Ryujinx.HLE/HOS/Services/SurfaceFlinger
parent461c24092ae6e148d896c18aa3e86220c89981f8 (diff)
IPC refactor part 2: Use ReplyAndReceive on HLE services and remove special handling from kernel (#1458)
* IPC refactor part 2: Use ReplyAndReceive on HLE services and remove special handling from kernel * Fix for applet transfer memory + some nits * Keep handles if possible to avoid server handle table exhaustion * Fix IPC ZeroFill bug * am: Correctly implement CreateManagedDisplayLayer and implement CreateManagedDisplaySeparableLayer CreateManagedDisplaySeparableLayer is requires since 10.x+ when appletResourceUserId != 0 * Make it exit properly * Make ServiceNotImplementedException show the full message again * Allow yielding execution to avoid starving other threads * Only wait if active * Merge IVirtualMemoryManager and IAddressSpaceManager * Fix Ro loading data from the wrong process Co-authored-by: Thog <me@thog.eu>
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/SurfaceFlinger')
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueue.cs12
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueCore.cs45
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueProducer.cs5
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs2
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs26
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/GraphicBuffer.cs12
6 files changed, 72 insertions, 30 deletions
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueue.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueue.cs
index 3dd21fde..2a9a6064 100644
--- a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueue.cs
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueue.cs
@@ -1,15 +1,15 @@
-using Ryujinx.HLE.HOS.Kernel.Process;
-
-namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
{
- class BufferQueue
+ static class BufferQueue
{
- public static void CreateBufferQueue(Switch device, KProcess process, out BufferQueueProducer producer, out BufferQueueConsumer consumer)
+ public static BufferQueueCore CreateBufferQueue(Switch device, long pid, out BufferQueueProducer producer, out BufferQueueConsumer consumer)
{
- BufferQueueCore core = new BufferQueueCore(device, process);
+ BufferQueueCore core = new BufferQueueCore(device, pid);
producer = new BufferQueueProducer(core);
consumer = new BufferQueueConsumer(core);
+
+ return core;
}
}
}
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueCore.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueCore.cs
index 7f6f6c31..389a980b 100644
--- a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueCore.cs
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueCore.cs
@@ -1,5 +1,5 @@
using Ryujinx.Common.Logging;
-using Ryujinx.HLE.HOS.Kernel.Process;
+using Ryujinx.HLE.HOS.Kernel;
using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types;
using System;
@@ -40,11 +40,13 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
private KEvent _waitBufferFreeEvent;
private KEvent _frameAvailableEvent;
- public KProcess Owner { get; }
+ public long Owner { get; }
+
+ public bool Active { get; private set; }
public const int BufferHistoryArraySize = 8;
- public BufferQueueCore(Switch device, KProcess process)
+ public BufferQueueCore(Switch device, long pid)
{
Slots = new BufferSlotArray();
IsAbandoned = false;
@@ -70,7 +72,9 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
_waitBufferFreeEvent = new KEvent(device.System.KernelContext);
_frameAvailableEvent = new KEvent(device.System.KernelContext);
- Owner = process;
+ Owner = pid;
+
+ Active = true;
BufferHistory = new BufferInfo[BufferHistoryArraySize];
EnableExternalEvent = true;
@@ -162,6 +166,16 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
}
}
+ public void PrepareForExit()
+ {
+ lock (Lock)
+ {
+ Active = false;
+
+ Monitor.PulseAll(Lock);
+ }
+ }
+
// TODO: Find an accurate way to handle a regular condvar here as this will wake up unwanted threads in some edge cases.
public void SignalDequeueEvent()
{
@@ -170,7 +184,11 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
public void WaitDequeueEvent()
{
- Monitor.Wait(Lock);
+ Monitor.Exit(Lock);
+
+ KernelStatic.YieldUntilCompletion(WaitForLock);
+
+ Monitor.Enter(Lock);
}
public void SignalIsAllocatingEvent()
@@ -180,7 +198,22 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
public void WaitIsAllocatingEvent()
{
- Monitor.Wait(Lock);
+ Monitor.Exit(Lock);
+
+ KernelStatic.YieldUntilCompletion(WaitForLock);
+
+ Monitor.Enter(Lock);
+ }
+
+ private void WaitForLock()
+ {
+ lock (Lock)
+ {
+ if (Active)
+ {
+ Monitor.Wait(Lock);
+ }
+ }
}
public void FreeBufferLocked(int slot)
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueProducer.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueProducer.cs
index 6ef49538..03df04ad 100644
--- a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueProducer.cs
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueProducer.cs
@@ -816,6 +816,11 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
}
Core.WaitDequeueEvent();
+
+ if (!Core.Active)
+ {
+ break;
+ }
}
}
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs
index 8ee943df..b3c81381 100644
--- a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs
@@ -7,7 +7,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
{
abstract class IHOSBinderDriver : IpcService
{
- public IHOSBinderDriver() {}
+ public IHOSBinderDriver() { }
[Command(0)]
// TransactParcel(s32, u32, u32, buffer<unknown, 5, 0>) -> buffer<unknown, 6, 0>
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
index 4713e50b..4927b40e 100644
--- a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
@@ -1,10 +1,7 @@
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu;
-using Ryujinx.HLE.HOS.Kernel.Process;
-using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap;
-using Ryujinx.HLE.HOS.Services.Nv.Types;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -40,7 +37,8 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
public int ProducerBinderId;
public IGraphicBufferProducer Producer;
public BufferItemConsumer Consumer;
- public KProcess Owner;
+ public BufferQueueCore Core;
+ public long Owner;
}
private class TextureCallbackInformation
@@ -84,7 +82,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
}
}
- public IGraphicBufferProducer OpenLayer(KProcess process, long layerId)
+ public IGraphicBufferProducer OpenLayer(long pid, long layerId)
{
bool needCreate;
@@ -95,13 +93,13 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
if (needCreate)
{
- CreateLayerFromId(process, layerId);
+ CreateLayerFromId(pid, layerId);
}
return GetProducerByLayerId(layerId);
}
- public IGraphicBufferProducer CreateLayer(KProcess process, out long layerId)
+ public IGraphicBufferProducer CreateLayer(long pid, out long layerId)
{
layerId = 1;
@@ -116,25 +114,26 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
}
}
- CreateLayerFromId(process, layerId);
+ CreateLayerFromId(pid, layerId);
return GetProducerByLayerId(layerId);
}
- private void CreateLayerFromId(KProcess process, long layerId)
+ private void CreateLayerFromId(long pid, long layerId)
{
lock (Lock)
{
Logger.Info?.Print(LogClass.SurfaceFlinger, $"Creating layer {layerId}");
- BufferQueue.CreateBufferQueue(_device, process, out BufferQueueProducer producer, out BufferQueueConsumer consumer);
+ BufferQueueCore core = BufferQueue.CreateBufferQueue(_device, pid, out BufferQueueProducer producer, out BufferQueueConsumer consumer);
_layers.Add(layerId, new Layer
{
ProducerBinderId = HOSBinderDriverServer.RegisterBinderObject(producer),
Producer = producer,
Consumer = new BufferItemConsumer(_device, consumer, 0, -1, false, this),
- Owner = process
+ Core = core,
+ Owner = pid
});
LastId = layerId;
@@ -345,6 +344,11 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
public void Dispose()
{
_isRunning = false;
+
+ foreach (Layer layer in _layers.Values)
+ {
+ layer.Core.PrepareForExit();
+ }
}
public void OnFrameAvailable(ref BufferItem item)
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/GraphicBuffer.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/GraphicBuffer.cs
index 8d63d9cc..d86ff21e 100644
--- a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/GraphicBuffer.cs
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Types/GraphicBuffer.cs
@@ -42,23 +42,23 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
Buffer = parcel.ReadUnmanagedType<NvGraphicBuffer>();
}
- public void IncrementNvMapHandleRefCount(KProcess process)
+ public void IncrementNvMapHandleRefCount(long pid)
{
- NvMapDeviceFile.IncrementMapRefCount(process, Buffer.NvMapId);
+ NvMapDeviceFile.IncrementMapRefCount(pid, Buffer.NvMapId);
for (int i = 0; i < Buffer.Surfaces.Length; i++)
{
- NvMapDeviceFile.IncrementMapRefCount(process, Buffer.Surfaces[i].NvMapHandle);
+ NvMapDeviceFile.IncrementMapRefCount(pid, Buffer.Surfaces[i].NvMapHandle);
}
}
- public void DecrementNvMapHandleRefCount(KProcess process)
+ public void DecrementNvMapHandleRefCount(long pid)
{
- NvMapDeviceFile.DecrementMapRefCount(process, Buffer.NvMapId);
+ NvMapDeviceFile.DecrementMapRefCount(pid, Buffer.NvMapId);
for (int i = 0; i < Buffer.Surfaces.Length; i++)
{
- NvMapDeviceFile.DecrementMapRefCount(process, Buffer.Surfaces[i].NvMapHandle);
+ NvMapDeviceFile.DecrementMapRefCount(pid, Buffer.Surfaces[i].NvMapHandle);
}
}