Adaptive vsync was partially supported: it worked if set before window
creation but not if toggled on afterwards, and wasn't mentioned in the
cvar description.
The immediate application of `vid_vsync` cvar changes was implented by
polling, which was ok for one cvar but I'll be making more vid_ cvars
apply immediately (no vid_restart needed), and don't want to poll for
things that rarely change every frame.
SDL is now queried for the current state of vsync instead of storing
what we believe to be the current state.
If the setting can't be applied the reason (as reported by SDL) is now
printed.
Signed-off-by: bones_was_here <bones_was_here@xonotic.au>
else
host.state = host_shutdown;
}
else
host.state = host_shutdown;
}
+
+ // Might need to re-enable vsync
+ Cvar_Callback(&vid_vsync);
cls.timedemo = host.restless = true;
cls.td_frames = -2; // skip the first frame
cls.demonum = -1; // stop demo loop
cls.timedemo = host.restless = true;
cls.td_frames = -2; // skip the first frame
cls.demonum = -1; // stop demo loop
+
+ // Might need to disable vsync
+ Cvar_Callback(&vid_vsync);
}
cls.state = ca_disconnected;
cl.islocalgame = false;
}
cls.state = ca_disconnected;
cl.islocalgame = false;
-
- cls.demoplayback = cls.timedemo = host.restless = false;
+ cls.demoplayback = cls.timedemo = host.restless = false;
+ Cvar_Callback(&vid_vsync); // might need to re-enable vsync
Cvar_Callback(&cl_netport);
Cvar_Callback(&cl_netport);
static qbool vid_usingmouse_relativeworks = false; // SDL2 workaround for unimplemented RelativeMouse mode
static qbool vid_usinghidecursor = false;
static qbool vid_hasfocus = false;
static qbool vid_usingmouse_relativeworks = false; // SDL2 workaround for unimplemented RelativeMouse mode
static qbool vid_usinghidecursor = false;
static qbool vid_hasfocus = false;
-static qbool vid_usingvsync = false;
static SDL_Joystick *vid_sdljoystick = NULL;
static SDL_GameController *vid_sdlgamecontroller = NULL;
static cvar_t joy_sdl2_trigger_deadzone = {CF_ARCHIVE | CF_CLIENT, "joy_sdl2_trigger_deadzone", "0.5", "deadzone for triggers to be registered as key presses"};
static SDL_Joystick *vid_sdljoystick = NULL;
static SDL_GameController *vid_sdlgamecontroller = NULL;
static cvar_t joy_sdl2_trigger_deadzone = {CF_ARCHIVE | CF_CLIENT, "joy_sdl2_trigger_deadzone", "0.5", "deadzone for triggers to be registered as key presses"};
return SDL_GL_ExtensionSupported(name);
}
return SDL_GL_ExtensionSupported(name);
}
+static void VID_SetVsync_c(cvar_t *var)
+{
+ signed char vsyncwanted = cls.timedemo ? 0 : bound(-1, vid_vsync.integer, 1);
+
+ if (!context)
+ return;
+ if (SDL_GL_GetSwapInterval() == vsyncwanted)
+ return;
+
+ if (SDL_GL_SetSwapInterval(vsyncwanted) >= 0)
+ Con_DPrintf("Vsync %s\n", vsyncwanted ? "activated" : "deactivated");
+ else
+ Con_Printf(CON_ERROR "ERROR: can't %s vsync because %s\n", vsyncwanted ? "activate" : "deactivate", SDL_GetError());
+}
+
void VID_Init (void)
{
#ifndef __IPHONEOS__
void VID_Init (void)
{
#ifndef __IPHONEOS__
R_RegisterModule("SDL", sdl_start, sdl_shutdown, sdl_newmap, NULL, NULL);
#endif
R_RegisterModule("SDL", sdl_start, sdl_shutdown, sdl_newmap, NULL, NULL);
#endif
+ Cvar_RegisterCallback(&vid_vsync, VID_SetVsync_c);
+
if (SDL_Init(SDL_INIT_VIDEO) < 0)
Sys_Error ("Failed to init SDL video subsystem: %s", SDL_GetError());
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
if (SDL_Init(SDL_INIT_VIDEO) < 0)
Sys_Error ("Failed to init SDL video subsystem: %s", SDL_GetError());
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
- SDL_GL_SetSwapInterval(bound(-1, vid_vsync.integer, 1));
- vid_usingvsync = (vid_vsync.integer != 0);
+ // apply vid_vsync
+ Cvar_Callback(&vid_vsync);
vid_hidden = false;
vid_activewindow = true;
vid_hidden = false;
vid_activewindow = true;
vid_activewindow = !vid_hidden && vid_hasfocus;
VID_UpdateGamma();
vid_activewindow = !vid_hidden && vid_hasfocus;
VID_UpdateGamma();
CHECKGLERROR
if (r_speeds.integer == 2 || gl_finish.integer)
GL_Finish();
CHECKGLERROR
if (r_speeds.integer == 2 || gl_finish.integer)
GL_Finish();
-
- vid_usevsync = (vid_vsync.integer && !cls.timedemo);
- if (vid_usingvsync != vid_usevsync)
- {
- vid_usingvsync = vid_usevsync;
- if (SDL_GL_SetSwapInterval(vid_usevsync != 0) >= 0)
- Con_DPrintf("Vsync %s\n", vid_usevsync ? "activated" : "deactivated");
- else
- Con_DPrintf("ERROR: can't %s vsync\n", vid_usevsync ? "activate" : "deactivate");
- }
SDL_GL_SwapWindow(window);
break;
}
SDL_GL_SwapWindow(window);
break;
}
cvar_t vid_touchscreen_xdpi = {CF_CLIENT, "vid_touchscreen_xdpi", "300", "Horizontal DPI of the screen (only valid on Android currently)"};
cvar_t vid_touchscreen_ydpi = {CF_CLIENT, "vid_touchscreen_ydpi", "300", "Vertical DPI of the screen (only valid on Android currently)"};
cvar_t vid_touchscreen_xdpi = {CF_CLIENT, "vid_touchscreen_xdpi", "300", "Horizontal DPI of the screen (only valid on Android currently)"};
cvar_t vid_touchscreen_ydpi = {CF_CLIENT, "vid_touchscreen_ydpi", "300", "Vertical DPI of the screen (only valid on Android currently)"};
-cvar_t vid_vsync = {CF_CLIENT | CF_ARCHIVE, "vid_vsync", "0", "sync to vertical blank, prevents 'tearing' (seeing part of one frame and part of another on the screen at the same time), automatically disabled when doing timedemo benchmarks"};
+cvar_t vid_vsync = {CF_CLIENT | CF_ARCHIVE, "vid_vsync", "0", "sync to vertical blank, prevents 'tearing' (seeing part of one frame and part of another on the screen at the same time) at the cost of latency, 1 always syncs and -1 is adaptive (stops syncing if the framerate drops, unsupported by some platforms), automatically disabled when doing timedemo benchmarks"};
cvar_t vid_mouse = {CF_CLIENT | CF_ARCHIVE, "vid_mouse", "1", "whether to use the mouse in windowed mode (fullscreen always does)"};
cvar_t vid_mouse_clickthrough = {CF_CLIENT | CF_ARCHIVE, "vid_mouse_clickthrough", "0", "mouse behavior in windowed mode: 0 = click to focus, 1 = allow interaction even if the window is not focused (click-through behaviour, can be useful when using third-party game overlays)"};
cvar_t vid_grabkeyboard = {CF_CLIENT | CF_ARCHIVE, "vid_grabkeyboard", "0", "whether to grab the keyboard when mouse is active (prevents use of volume control keys, music player keys, etc on some keyboards)"};
cvar_t vid_mouse = {CF_CLIENT | CF_ARCHIVE, "vid_mouse", "1", "whether to use the mouse in windowed mode (fullscreen always does)"};
cvar_t vid_mouse_clickthrough = {CF_CLIENT | CF_ARCHIVE, "vid_mouse_clickthrough", "0", "mouse behavior in windowed mode: 0 = click to focus, 1 = allow interaction even if the window is not focused (click-through behaviour, can be useful when using third-party game overlays)"};
cvar_t vid_grabkeyboard = {CF_CLIENT | CF_ARCHIVE, "vid_grabkeyboard", "0", "whether to grab the keyboard when mouse is active (prevents use of volume control keys, music player keys, etc on some keyboards)"};