From a2c6cd51329a4b8fe4eba0d47cb4d4ce2084876d Mon Sep 17 00:00:00 2001 From: riperiperi Date: Tue, 12 Oct 2021 22:29:50 +0100 Subject: [PATCH] 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. --- .../Services/SurfaceFlinger/SurfaceFlinger.cs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs index 6e56aefa..39aebde5 100644 --- a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs +++ b/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)