From 6339872da830e791cedbed31438eed2c0d0c599f Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sat, 28 Oct 2023 14:19:37 +0900 Subject: [PATCH] internal/graphicscommand: disable asynchronous rendering when vsync is on Asynchronouse rendering was introduced at #2664, but apparently this caused a delay between a game's update and its rendering. Disable this when vsync is on. When vsync is off, we should not have to care the delay since new renderings keep to come. Rather, asynchronous renderings improves FPS. Updates #2664 Updates #2822 --- internal/graphicscommand/commandqueue.go | 24 ++++++++++++++++++++---- internal/ui/ui_glfw.go | 5 ++++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/internal/graphicscommand/commandqueue.go b/internal/graphicscommand/commandqueue.go index f522caa1c..e419fe281 100644 --- a/internal/graphicscommand/commandqueue.go +++ b/internal/graphicscommand/commandqueue.go @@ -27,6 +27,16 @@ import ( "github.com/hajimehoshi/ebiten/v2/internal/shaderir" ) +var vsyncEnabled int32 = 1 + +func SetVsyncEnabled(enabled bool) { + if enabled { + atomic.StoreInt32(&vsyncEnabled, 1) + } else { + atomic.StoreInt32(&vsyncEnabled, 0) + } +} + // FlushCommands flushes the command queue and present the screen if needed. // If endFrame is true, the current screen might be used to present. func FlushCommands(graphicsDriver graphicsdriver.Graphics, endFrame bool, swapBuffersForGL func()) error { @@ -154,10 +164,16 @@ func (q *commandQueue) Flush(graphicsDriver graphicsdriver.Graphics, endFrame bo } var sync bool - for _, c := range q.commands { - if c.NeedsSync() { - sync = true - break + // Disable asynchrnous rendering when vsync is on, as this causes a rendering delay (#2822). + if endFrame && atomic.LoadInt32(&vsyncEnabled) != 0 { + sync = true + } + if !sync { + for _, c := range q.commands { + if c.NeedsSync() { + sync = true + break + } } } diff --git a/internal/ui/ui_glfw.go b/internal/ui/ui_glfw.go index c93a0f0c7..d4e54d92f 100644 --- a/internal/ui/ui_glfw.go +++ b/internal/ui/ui_glfw.go @@ -30,6 +30,7 @@ import ( "github.com/hajimehoshi/ebiten/v2/internal/file" "github.com/hajimehoshi/ebiten/v2/internal/gamepad" "github.com/hajimehoshi/ebiten/v2/internal/glfw" + "github.com/hajimehoshi/ebiten/v2/internal/graphicscommand" "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver" "github.com/hajimehoshi/ebiten/v2/internal/hook" "github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk" @@ -1317,8 +1318,10 @@ func (u *UserInterface) setFPSMode(fpsMode FPSModeType) error { return err } + vsyncEnabled := u.fpsMode == FPSModeVsyncOn + graphicscommand.SetVsyncEnabled(vsyncEnabled) u.renderThread.CallAsync(func() { - u.graphicsDriver.SetVsyncEnabled(u.fpsMode == FPSModeVsyncOn) + u.graphicsDriver.SetVsyncEnabled(vsyncEnabled) }) return nil