aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2022-07-06 13:37:36 -0300
committerGitHub <noreply@github.com>2022-07-06 13:37:36 -0300
commit55e97959b9720e2efbe2451c38e0610422335603 (patch)
tree4a78a8f6c4377061d160679da789a465956d9de5
parentf7ef6364b79ba04af5c7bf0f5ec77fbb6b4aae29 (diff)
Fix Vi managed and stray layers open/close/destroy (#3438)1.1.166
* Fix Vi managed and stray layers open/close/destroy * OpenLayer should set the state to ManagedOpened
-rw-r--r--Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ISelfController.cs6
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/LayerState.cs10
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs150
-rw-r--r--Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/IManagerDisplayService.cs6
-rw-r--r--Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs17
5 files changed, 137 insertions, 52 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ISelfController.cs b/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ISelfController.cs
index 2af80f6e..d6e34d21 100644
--- a/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ISelfController.cs
+++ b/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ISelfController.cs
@@ -217,7 +217,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
// CreateManagedDisplayLayer() -> u64
public ResultCode CreateManagedDisplayLayer(ServiceCtx context)
{
- context.Device.System.SurfaceFlinger.CreateLayer(_pid, out long layerId);
+ context.Device.System.SurfaceFlinger.CreateLayer(out long layerId, _pid);
context.Device.System.SurfaceFlinger.SetRenderLayer(layerId);
context.ResponseData.Write(layerId);
@@ -238,8 +238,8 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
// CreateManagedDisplaySeparableLayer() -> (u64, u64)
public ResultCode CreateManagedDisplaySeparableLayer(ServiceCtx context)
{
- context.Device.System.SurfaceFlinger.CreateLayer(_pid, out long displayLayerId);
- context.Device.System.SurfaceFlinger.CreateLayer(_pid, out long recordingLayerId);
+ context.Device.System.SurfaceFlinger.CreateLayer(out long displayLayerId, _pid);
+ context.Device.System.SurfaceFlinger.CreateLayer(out long recordingLayerId, _pid);
context.Device.System.SurfaceFlinger.SetRenderLayer(displayLayerId);
context.ResponseData.Write(displayLayerId);
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/LayerState.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/LayerState.cs
new file mode 100644
index 00000000..5f014e13
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/LayerState.cs
@@ -0,0 +1,10 @@
+namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
+{
+ enum LayerState
+ {
+ NotInitialized,
+ ManagedClosed,
+ ManagedOpened,
+ Stray
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
index be2e15bd..8fa27905 100644
--- a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
@@ -11,6 +11,8 @@ using System.Threading;
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
{
+ using ResultCode = Ryujinx.HLE.HOS.Services.Vi.ResultCode;
+
class SurfaceFlinger : IConsumerListener, IDisposable
{
private const int TargetFps = 60;
@@ -45,6 +47,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
public BufferItemConsumer Consumer;
public BufferQueueCore Core;
public ulong Owner;
+ public LayerState State;
}
private class TextureCallbackInformation
@@ -92,24 +95,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
}
}
- public IGraphicBufferProducer OpenLayer(ulong pid, long layerId)
- {
- bool needCreate;
-
- lock (Lock)
- {
- needCreate = GetLayerByIdLocked(layerId) == null;
- }
-
- if (needCreate)
- {
- CreateLayerFromId(pid, layerId);
- }
-
- return GetProducerByLayerId(layerId);
- }
-
- public IGraphicBufferProducer CreateLayer(ulong pid, out long layerId)
+ public IGraphicBufferProducer CreateLayer(out long layerId, ulong pid, LayerState initialState = LayerState.ManagedClosed)
{
layerId = 1;
@@ -124,12 +110,12 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
}
}
- CreateLayerFromId(pid, layerId);
+ CreateLayerFromId(pid, layerId, initialState);
return GetProducerByLayerId(layerId);
}
- private void CreateLayerFromId(ulong pid, long layerId)
+ private void CreateLayerFromId(ulong pid, long layerId, LayerState initialState)
{
lock (Lock)
{
@@ -148,39 +134,129 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
Producer = producer,
Consumer = new BufferItemConsumer(_device, consumer, 0, -1, false, this),
Core = core,
- Owner = pid
+ Owner = pid,
+ State = initialState
});
}
}
- public bool CloseLayer(long layerId)
+ public ResultCode OpenLayer(ulong pid, long layerId, out IBinder producer)
+ {
+ Layer layer = GetLayerByIdLocked(layerId);
+
+ if (layer == null || layer.State != LayerState.ManagedClosed)
+ {
+ producer = null;
+
+ return ResultCode.InvalidArguments;
+ }
+
+ layer.State = LayerState.ManagedOpened;
+ producer = layer.Producer;
+
+ return ResultCode.Success;
+ }
+
+ public ResultCode CloseLayer(long layerId)
{
lock (Lock)
{
Layer layer = GetLayerByIdLocked(layerId);
- if (layer != null)
+ if (layer == null)
{
- HOSBinderDriverServer.UnregisterBinderObject(layer.ProducerBinderId);
+ Logger.Error?.Print(LogClass.SurfaceFlinger, $"Failed to close layer {layerId}");
+
+ return ResultCode.InvalidValue;
}
- bool removed = _layers.Remove(layerId);
+ CloseLayer(layerId, layer);
+
+ return ResultCode.Success;
+ }
+ }
- // If the layer was removed and the current in use, we need to change the current layer in use.
- if (removed && RenderLayerId == layerId)
+ public ResultCode DestroyManagedLayer(long layerId)
+ {
+ lock (Lock)
+ {
+ Layer layer = GetLayerByIdLocked(layerId);
+
+ if (layer == null)
{
- // If no layer is availaible, reset to default value.
- if (_layers.Count == 0)
- {
- SetRenderLayer(0);
- }
- else
- {
- SetRenderLayer(_layers.Last().Key);
- }
+ Logger.Error?.Print(LogClass.SurfaceFlinger, $"Failed to destroy managed layer {layerId} (not found)");
+
+ return ResultCode.InvalidValue;
+ }
+
+ if (layer.State != LayerState.ManagedClosed && layer.State != LayerState.ManagedOpened)
+ {
+ Logger.Error?.Print(LogClass.SurfaceFlinger, $"Failed to destroy managed layer {layerId} (permission denied)");
+
+ return ResultCode.PermissionDenied;
+ }
+
+ HOSBinderDriverServer.UnregisterBinderObject(layer.ProducerBinderId);
+
+ if (_layers.Remove(layerId) && layer.State == LayerState.ManagedOpened)
+ {
+ CloseLayer(layerId, layer);
+ }
+
+ return ResultCode.Success;
+ }
+ }
+
+ public ResultCode DestroyStrayLayer(long layerId)
+ {
+ lock (Lock)
+ {
+ Layer layer = GetLayerByIdLocked(layerId);
+
+ if (layer == null)
+ {
+ Logger.Error?.Print(LogClass.SurfaceFlinger, $"Failed to destroy stray layer {layerId} (not found)");
+
+ return ResultCode.InvalidValue;
}
- return removed;
+ if (layer.State != LayerState.Stray)
+ {
+ Logger.Error?.Print(LogClass.SurfaceFlinger, $"Failed to destroy stray layer {layerId} (permission denied)");
+
+ return ResultCode.PermissionDenied;
+ }
+
+ HOSBinderDriverServer.UnregisterBinderObject(layer.ProducerBinderId);
+
+ if (_layers.Remove(layerId))
+ {
+ CloseLayer(layerId, layer);
+ }
+
+ return ResultCode.Success;
+ }
+ }
+
+ private void CloseLayer(long layerId, Layer layer)
+ {
+ // If the layer was removed and the current in use, we need to change the current layer in use.
+ if (RenderLayerId == layerId)
+ {
+ // If no layer is availaible, reset to default value.
+ if (_layers.Count == 0)
+ {
+ SetRenderLayer(0);
+ }
+ else
+ {
+ SetRenderLayer(_layers.Last().Key);
+ }
+ }
+
+ if (layer.State == LayerState.ManagedOpened)
+ {
+ layer.State = LayerState.ManagedClosed;
}
}
diff --git a/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/IManagerDisplayService.cs b/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/IManagerDisplayService.cs
index 096c7a30..f40a053c 100644
--- a/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/IManagerDisplayService.cs
+++ b/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/IManagerDisplayService.cs
@@ -35,7 +35,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService
ulong pid = context.Device.System.AppletState.AppletResourceUserIds.GetData<ulong>((int)appletResourceUserId);
- context.Device.System.SurfaceFlinger.CreateLayer(pid, out long layerId);
+ context.Device.System.SurfaceFlinger.CreateLayer(out long layerId, pid);
context.Device.System.SurfaceFlinger.SetRenderLayer(layerId);
context.ResponseData.Write(layerId);
@@ -49,9 +49,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService
{
long layerId = context.RequestData.ReadInt64();
- context.Device.System.SurfaceFlinger.CloseLayer(layerId);
-
- return ResultCode.Success;
+ return context.Device.System.SurfaceFlinger.DestroyManagedLayer(layerId);
}
[CommandHipc(2012)] // 7.0.0+
diff --git a/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs b/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs
index da55c116..640e8be4 100644
--- a/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs
+++ b/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs
@@ -237,7 +237,12 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
long userId = context.RequestData.ReadInt64();
ulong parcelPtr = context.Request.ReceiveBuff[0].Position;
- IBinder producer = context.Device.System.SurfaceFlinger.OpenLayer(context.Request.HandleDesc.PId, layerId);
+ ResultCode result = context.Device.System.SurfaceFlinger.OpenLayer(context.Request.HandleDesc.PId, layerId, out IBinder producer);
+
+ if (result != ResultCode.Success)
+ {
+ return result;
+ }
context.Device.System.SurfaceFlinger.SetRenderLayer(layerId);
@@ -260,9 +265,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
{
long layerId = context.RequestData.ReadInt64();
- context.Device.System.SurfaceFlinger.CloseLayer(layerId);
-
- return ResultCode.Success;
+ return context.Device.System.SurfaceFlinger.CloseLayer(layerId);
}
[CommandHipc(2030)]
@@ -275,7 +278,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
ulong parcelPtr = context.Request.ReceiveBuff[0].Position;
// TODO: support multi display.
- IBinder producer = context.Device.System.SurfaceFlinger.CreateLayer(0, out long layerId);
+ IBinder producer = context.Device.System.SurfaceFlinger.CreateLayer(out long layerId, 0, LayerState.Stray);
context.Device.System.SurfaceFlinger.SetRenderLayer(layerId);
@@ -299,9 +302,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
{
long layerId = context.RequestData.ReadInt64();
- context.Device.System.SurfaceFlinger.CloseLayer(layerId);
-
- return ResultCode.Success;
+ return context.Device.System.SurfaceFlinger.DestroyStrayLayer(layerId);
}
[CommandHipc(2101)]