diff options
| author | riperiperi <rhy3756547@hotmail.com> | 2021-10-12 22:29:50 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-10-12 23:29:50 +0200 |
| commit | a2c6cd51329a4b8fe4eba0d47cb4d4ce2084876d (patch) | |
| tree | b1f54dbf6a017b94b6a74ecd5d080defc3d6902d | |
| parent | 0bce4a074a32099152ac65cb49b2a75051e3ba8b (diff) | |
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.
| -rw-r--r-- | Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs | 28 |
1 files 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) |
