aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2021-10-12 22:29:50 +0100
committerGitHub <noreply@github.com>2021-10-12 23:29:50 +0200
commita2c6cd51329a4b8fe4eba0d47cb4d4ce2084876d (patch)
treeb1f54dbf6a017b94b6a74ecd5d080defc3d6902d
parent0bce4a074a32099152ac65cb49b2a75051e3ba8b (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.cs28
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)