aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE
diff options
context:
space:
mode:
authorMary <me@thog.eu>2021-04-13 02:56:16 +0200
committerGitHub <noreply@github.com>2021-04-13 02:56:16 +0200
commit73881fad1995e079eae3e728cb2f4c657886e476 (patch)
tree957679f0a3e2d8f4bcebb10dba298bfe4671774f /Ryujinx.HLE
parent5cb83293bc25fa707a33e7fca23bf3d1f4a6db26 (diff)
Surface Flinger: Fix an oversight when closing a layer (#2192)
* Surface Flinger: Fix an oversight when closing a layer As the title say. I also took the liberty of changing the logic on how we select the current layer being rendered to make it more explicit when opening and creating layers. NOTE: Found by Ac_k. * check for RenderLayerId and not the dictionary size This fix a possible race condition between the time you create a layer and set the one currently used for rendering
Diffstat (limited to 'Ryujinx.HLE')
-rw-r--r--Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ISelfController.cs5
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs37
-rw-r--r--Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/IManagerDisplayService.cs1
-rw-r--r--Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs4
4 files changed, 38 insertions, 9 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 b2cc7160..7e0c7e64 100644
--- a/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ISelfController.cs
+++ b/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ISelfController.cs
@@ -218,6 +218,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
public ResultCode CreateManagedDisplayLayer(ServiceCtx context)
{
context.Device.System.SurfaceFlinger.CreateLayer(_pid, out long layerId);
+ context.Device.System.SurfaceFlinger.SetRenderLayer(layerId);
context.ResponseData.Write(layerId);
@@ -228,9 +229,9 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
// CreateManagedDisplaySeparableLayer() -> (u64, u64)
public ResultCode CreateManagedDisplaySeparableLayer(ServiceCtx context)
{
- // NOTE: first create the recoding layer and then the display one because right now Surface Flinger only use the last id.
- context.Device.System.SurfaceFlinger.CreateLayer(_pid, out long recordingLayerId);
context.Device.System.SurfaceFlinger.CreateLayer(_pid, out long displayLayerId);
+ context.Device.System.SurfaceFlinger.CreateLayer(_pid, out long recordingLayerId);
+ context.Device.System.SurfaceFlinger.SetRenderLayer(displayLayerId);
context.ResponseData.Write(displayLayerId);
context.ResponseData.Write(recordingLayerId);
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
index 297acdda..556e6a3b 100644
--- a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
@@ -7,6 +7,7 @@ using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap;
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Linq;
using System.Threading;
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
@@ -36,7 +37,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
private readonly object Lock = new object();
- public long LastId { get; private set; }
+ public long RenderLayerId { get; private set; }
private class Layer
{
@@ -57,7 +58,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
{
_device = device;
_layers = new Dictionary<long, Layer>();
- LastId = 0;
+ RenderLayerId = 0;
_composerThread = new Thread(HandleComposition)
{
@@ -150,8 +151,6 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
Core = core,
Owner = pid
});
-
- LastId = layerId;
}
}
@@ -166,7 +165,31 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
HOSBinderDriverServer.UnregisterBinderObject(layer.ProducerBinderId);
}
- return _layers.Remove(layerId);
+ bool removed = _layers.Remove(layerId);
+
+ // If the layer was removed and the current in use, we need to change the current layer in use.
+ if (removed && RenderLayerId == layerId)
+ {
+ // If no layer is availaible, reset to default value.
+ if (_layers.Count == 0)
+ {
+ SetRenderLayer(0);
+ }
+ else
+ {
+ SetRenderLayer(_layers.Last().Key);
+ }
+ }
+
+ return removed;
+ }
+ }
+
+ public void SetRenderLayer(long layerId)
+ {
+ lock (Lock)
+ {
+ RenderLayerId = layerId;
}
}
@@ -263,12 +286,12 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
lock (Lock)
{
// TODO: support multilayers (& multidisplay ?)
- if (_layers.Count == 0)
+ if (RenderLayerId == 0)
{
return;
}
- Layer layer = GetLayerByIdLocked(LastId);
+ Layer layer = GetLayerByIdLocked(RenderLayerId);
Status acquireStatus = layer.Consumer.AcquireBuffer(out BufferItem item, 0);
diff --git a/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/IManagerDisplayService.cs b/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/IManagerDisplayService.cs
index 6b874722..4d3bef50 100644
--- a/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/IManagerDisplayService.cs
+++ b/Ryujinx.HLE/HOS/Services/Vi/RootService/ApplicationDisplayService/IManagerDisplayService.cs
@@ -22,6 +22,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService
long pid = context.Device.System.AppletState.AppletResourceUserIds.GetData<long>((int)appletResourceUserId);
context.Device.System.SurfaceFlinger.CreateLayer(pid, out long layerId);
+ context.Device.System.SurfaceFlinger.SetRenderLayer(layerId);
context.ResponseData.Write(layerId);
diff --git a/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs b/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs
index b521ae92..1620ef21 100644
--- a/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs
+++ b/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs
@@ -126,6 +126,8 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
IBinder producer = context.Device.System.SurfaceFlinger.OpenLayer(context.Request.HandleDesc.PId, layerId);
+ context.Device.System.SurfaceFlinger.SetRenderLayer(layerId);
+
Parcel parcel = new Parcel(0x28, 0x4);
parcel.WriteObject(producer, "dispdrv\0");
@@ -164,6 +166,8 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
IBinder producer = context.Device.System.SurfaceFlinger.CreateLayer(0, out long layerId);
+ context.Device.System.SurfaceFlinger.SetRenderLayer(layerId);
+
Parcel parcel = new Parcel(0x28, 0x4);
parcel.WriteObject(producer, "dispdrv\0");