Jelajahi Sumber

Enqueue frame before signalling the frame is ready. (#2722)

It seems that certain games (Link's Awakening, Xenoblade DE) had their fences reached already when posting framebuffers, so the signal that a frame was ready would go out _before_ the frame was enqueued, and the render loop would fail to dequeue anything and "skip" a frame.

This was resulting in their performance lowering dramatically after some loading transitions, as a frame signal would be consumed and presentation would be one frame behind.

It's possible this might have eventually caused deadlocks in these games or others, if it happened twice.
riperiperi 4 tahun lalu
induk
melakukan
a2c6cd5132
1 mengubah file dengan 14 tambahan dan 14 penghapusan
  1. 14 14
      Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs

+ 14 - 14
Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs

@@ -370,20 +370,6 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
                 Item  = item
             };
 
-            if (item.Fence.FenceCount == 0)
-            {
-                _device.Gpu.Window.SignalFrameReady();
-                _device.Gpu.GPFifo.Interrupt();
-            }
-            else
-            {
-                item.Fence.RegisterCallback(_device.Gpu, () =>
-                {
-                    _device.Gpu.Window.SignalFrameReady();
-                    _device.Gpu.GPFifo.Interrupt();
-                });
-            }
-
             _device.Gpu.Window.EnqueueFrameThreadSafe(
                 layer.Owner,
                 frameBufferAddress,
@@ -398,6 +384,20 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
                 AcquireBuffer,
                 ReleaseBuffer,
                 textureCallbackInformation);
+
+            if (item.Fence.FenceCount == 0)
+            {
+                _device.Gpu.Window.SignalFrameReady();
+                _device.Gpu.GPFifo.Interrupt();
+            }
+            else
+            {
+                item.Fence.RegisterCallback(_device.Gpu, () =>
+                {
+                    _device.Gpu.Window.SignalFrameReady();
+                    _device.Gpu.GPFifo.Interrupt();
+                });
+            }
         }
 
         private void ReleaseBuffer(object obj)