From 81f848e54f4c66af82297b4c9d26cacf79ec10be Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Sun, 2 Oct 2022 18:50:03 -0300
Subject: [PATCH] Allow Surface Flinger frame enqueue after process has exited
 (#3733)

---
 Ryujinx.Graphics.Gpu/Window.cs                |  7 +++--
 .../Services/SurfaceFlinger/SurfaceFlinger.cs | 27 +++++++++++--------
 2 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/Ryujinx.Graphics.Gpu/Window.cs b/Ryujinx.Graphics.Gpu/Window.cs
index 8ad70c7f1..18320c74d 100644
--- a/Ryujinx.Graphics.Gpu/Window.cs
+++ b/Ryujinx.Graphics.Gpu/Window.cs
@@ -123,7 +123,8 @@ namespace Ryujinx.Graphics.Gpu
         /// <param name="releaseCallback">Texture release callback</param>
         /// <param name="userObj">User defined object passed to the release callback</param>
         /// <exception cref="ArgumentException">Thrown when <paramref name="pid"/> is invalid</exception>
-        public void EnqueueFrameThreadSafe(
+        /// <returns>True if the frame was added to the queue, false otherwise</returns>
+        public bool EnqueueFrameThreadSafe(
             ulong                      pid,
             ulong                      address,
             int                        width,
@@ -140,7 +141,7 @@ namespace Ryujinx.Graphics.Gpu
         {
             if (!_context.PhysicalMemoryRegistry.TryGetValue(pid, out var physicalMemory))
             {
-                throw new ArgumentException("The PID is invalid or the process was not registered", nameof(pid));
+                return false;
             }
 
             FormatInfo formatInfo = new FormatInfo(format, 1, 1, bytesPerPixel, 4);
@@ -184,6 +185,8 @@ namespace Ryujinx.Graphics.Gpu
                 acquireCallback,
                 releaseCallback,
                 userObj));
+
+            return true;
         }
 
         /// <summary>
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
index b24a94db6..c7cddf100 100644
--- a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
@@ -453,7 +453,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
                 Item  = item
             };
 
-            _device.Gpu.Window.EnqueueFrameThreadSafe(
+            if (_device.Gpu.Window.EnqueueFrameThreadSafe(
                 layer.Owner,
                 frameBufferAddress,
                 frameBufferWidth,
@@ -466,20 +466,25 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
                 crop,
                 AcquireBuffer,
                 ReleaseBuffer,
-                textureCallbackInformation);
-
-            if (item.Fence.FenceCount == 0)
+                textureCallbackInformation))
             {
-                _device.Gpu.Window.SignalFrameReady();
-                _device.Gpu.GPFifo.Interrupt();
-            }
-            else
-            {
-                item.Fence.RegisterCallback(_device.Gpu, (x) =>
+                if (item.Fence.FenceCount == 0)
                 {
                     _device.Gpu.Window.SignalFrameReady();
                     _device.Gpu.GPFifo.Interrupt();
-                });
+                }
+                else
+                {
+                    item.Fence.RegisterCallback(_device.Gpu, (x) =>
+                    {
+                        _device.Gpu.Window.SignalFrameReady();
+                        _device.Gpu.GPFifo.Interrupt();
+                    });
+                }
+            }
+            else
+            {
+                ReleaseBuffer(textureCallbackInformation);
             }
         }