luciusDXL / TheForceEngine

Modern "Jedi Engine" replacement supporting Dark Forces, mods, and in the future Outlaws.
https://TheForceEngine.github.io
GNU General Public License v2.0
992 stars 72 forks source link

[🐛] Vsync does not stick #432

Open JakeSmarter opened 3 months ago

JakeSmarter commented 3 months ago

Linux Flathub v1.10.000-28-ge19bcde1+

No matter what I do in the UI but Vsync never sticks ~nor is saved in the settings~. I am not even sure that once I check it is actually activated.

mlauss2 commented 3 months ago

What about all the other options, do they stick? (apart from the resolution issue you reported) Is "settings.ini" of the flatpak build writable?

Obviously I only checked my "normal" build, but the "vsync=xxx" in settings.ini is updated as soon as the checkbox is toggled.

JakeSmarter commented 3 months ago

Is "settings.ini" of the flatpak build writable?

Yes, it is. So, apparently Vsync is saved in the settings.ini but you cannot tell for sure, except from the log.

[Display] Vertical Sync enabled.

Try checking Vsync and then exiting and launching multiple time into the graphics menu. Try also checking Vsync while in the game, resume the game and then go back to the graphics menu. Vsync always displays unchecked. It just does not stick. :wink:

mlauss2 commented 3 months ago

I can't reproduce at least on x86 with my own build. Vsync works as it should (fps counter), setting is preserved over multiple invocations and restarts.

JakeSmarter commented 3 months ago

Vsync is preserved for me too but the checkbox is cleared whenever I go into the graphics menu. It also does not matter which renderer I use (and should not by design).

luciusDXL commented 3 months ago

Vsync checkbox works on Windows (that is, it reflects the current state of vsync, saving vsync state works, etc.), so I'm not sure why it would fail to update on Linux. Is anyone else seeing this behavior on Linux?

JakeSmarter commented 3 months ago

I have no idea why this happens on Linux either, I would have to look at the code to perhaps get some clue.

I have discovered that when Vsync is set to true in settings.ini and I go into the graphics menu right after I launch TFE (do not start a new or load a game) the checkbox is cleared after about one or two seconds. :thinking: Strange, very strange.

mlauss2 commented 3 months ago

It can happen: See TFE_RenderBackend::getVSyncEnabled()

return SDL_GL_GetSwapInterval() > 0;

and TFE_System::update() line 139:

s_synced = TFE_RenderBackend::getVsyncEnabled();

So if SDL for some reason has reset the swap interval to zero, Vsync would become disabled here again, since the UI reads/writes the "s_synced" variable.

@JakeSmarter can you please apply this patch and see if it prints anything in the logfile/console when you toggle VSync?

index 960dc91e..b0303ab8 100644
--- a/TheForceEngine/TFE_RenderBackend/Win32OpenGL/renderBackend.cpp
+++ b/TheForceEngine/TFE_RenderBackend/Win32OpenGL/renderBackend.cpp
@@ -258,7 +258,9 @@ namespace TFE_RenderBackend

        void enableVsync(bool enable)
        {
-               SDL_GL_SetSwapInterval(enable ? 1 : 0);
+               int ret = SDL_GL_SetSwapInterval(enable ? 1 : 0);
+               if (ret != 0)
+                       TFE_System::logWrite(LOG_MSG, "RenderBackend", "SetSwapInterval(%d) failed: %d %s", enable, ret, SDL_GetError());
        }

        void setClearColor(const f32* color)

Also out of curiosity, which SDL2 version do you have? There was a bug fixed late last year in SDL2/3 about vsync...

mlauss2 commented 3 months ago

Looking the the SDL source, this can fail if the underlying windowing system (X11 or EGL) does not support any of [EXT,MESA,SGI]_swap_control extensions (or the extension cannot set the desired swap interval), but the patch above should print the precise reason it fails.

luciusDXL commented 3 months ago

Ok, that makes sense - I need to check if setting the swap interval works instead of assuming it does (which is the case on Windows).

JakeSmarter commented 3 months ago

@mlauss2 Could you please provide a branch in your repo to ease building and testing. Thank you.

mlauss2 commented 3 months ago

@mlauss2 Could you please provide a branch in your repo to ease building and testing. Thank you.

https://github.com/mlauss2/TheForceEngine/tree/vsynctest

JakeSmarter commented 3 months ago

Also out of curiosity, which SDL2 version do you have? There was a bug fixed late last year in SDL2/3 about vsync...

I am not sure what version the org.freedesktop.Platform//23.08 runtime ships with. The main SDL2 file goes by the name libSDL2-2.0.so.0.2800.5 and SONAME says libSDL2-2.0.so.0. :man_shrugging: So, I do not know. Anyway, I do not think the root cause is in SDL2.

grep -En 'SDL\w*VERSION' /usr/include/SDL2/SDL_version.h
60:#define SDL_MAJOR_VERSION   2
61:#define SDL_MINOR_VERSION   28

So, I guess it is SDL2 2.28.5. :shrug:

JakeSmarter commented 3 months ago

Please excuse the delay. I have been able to test vsynctest v1.10.000-29-g51e3271a but the log does not say anything new and the behavior did not change. The “Vsync” checkbox continues to be cleared a few seconds after you enter (no matter whether from in-game or directly from the main menu) the graphics menu. There are no new log messages either, no matter whether you set or clear the “Vsync” checkbox. :shrug:

mlauss2 commented 3 months ago

Can you please post the contents of the_force_engine.log or complete console output?

JakeSmarter commented 3 months ago

@mlauss2 For best comparable results please try to run the Flathub release if you can. You should get identical behavior on x86_64. Again, I do not think this issue is specific to any architecture, although it could be a device driver bug that only exists on the V3D and aarch64 combo. We cannot rule out SDL2 as the culprit yet either. However, something tells me that this is rather a bug in the UI code. Anyway, we can try building against the latest SDL2 release and see what happens.

mlauss2 commented 3 months ago

it could be a device driver bug that only exists on the V3D and aarch64 combo.

That is my line of thinking at the moment. Please post the log output somewhere, I need it to check the SDL codepath.