Skip to content

Commit 772d8b3

Browse files
committed
Disable vsync with multi-viewport on multiple monitors and different refresh rates
1 parent fd55f4f commit 772d8b3

File tree

3 files changed

+87
-3
lines changed

3 files changed

+87
-3
lines changed

platforms/shared/desktop/application.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ static bool sdl_init(void)
339339
#endif
340340

341341
display_set_vsync(config_video.sync);
342+
display_check_mixed_refresh_rates();
342343

343344
SDL_SetWindowMinimumSize(application_sdl_window, (int)(500 * content_scale), (int)(300 * content_scale));
344345

@@ -474,11 +475,23 @@ static void sdl_events_app(const SDL_Event* event)
474475
if (new_display != current_display_id)
475476
{
476477
current_display_id = new_display;
477-
if (config_video.sync)
478+
display_check_mixed_refresh_rates();
479+
if (config_video.sync && !display_is_vsync_forced_off())
478480
display_recreate_gl_context();
481+
else
482+
{
483+
display_request_gl_context_recreate();
484+
display_update_frame_pacing();
485+
}
479486
}
480487
break;
481488
}
489+
case SDL_EVENT_DISPLAY_ADDED:
490+
case SDL_EVENT_DISPLAY_REMOVED:
491+
{
492+
display_check_mixed_refresh_rates();
493+
break;
494+
}
482495
case (SDL_EVENT_MOUSE_MOTION):
483496
{
484497
mouse_last_motion_time = SDL_GetTicks();

platforms/shared/desktop/display.cpp

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ static Uint64 frame_time_end = 0;
3535
static int monitor_refresh_rate = 60;
3636
static int vsync_frames_per_emu_frame = 1;
3737
static int vsync_frame_counter = 0;
38+
static int last_vsync_state = -1;
39+
static bool multi_monitor_mixed_refresh = false;
40+
static bool pending_gl_context_recreate = false;
3841

3942
void display_begin_frame(void)
4043
{
@@ -107,9 +110,11 @@ bool display_should_run_emu_frame(void)
107110

108111
void display_set_vsync(bool enabled)
109112
{
113+
bool effective = enabled && !display_is_vsync_forced_off();
110114
SDL_GL_SetSwapInterval(0);
111-
if (enabled)
115+
if (effective)
112116
SDL_GL_SetSwapInterval(1);
117+
last_vsync_state = effective ? 1 : 0;
113118
display_update_frame_pacing();
114119
}
115120

@@ -140,6 +145,69 @@ void display_update_frame_pacing(void)
140145
Debug("Monitor refresh rate: %d Hz, vsync frames per emu frame: %d", monitor_refresh_rate, vsync_frames_per_emu_frame);
141146
}
142147

148+
void display_check_mixed_refresh_rates(void)
149+
{
150+
int count = 0;
151+
SDL_DisplayID* displays = SDL_GetDisplays(&count);
152+
153+
if (!displays || count <= 1)
154+
{
155+
if (displays)
156+
SDL_free(displays);
157+
multi_monitor_mixed_refresh = false;
158+
return;
159+
}
160+
161+
int first_rate = 0;
162+
bool mixed = false;
163+
164+
for (int i = 0; i < count; i++)
165+
{
166+
const SDL_DisplayMode* mode = SDL_GetCurrentDisplayMode(displays[i]);
167+
if (mode && mode->refresh_rate > 0)
168+
{
169+
int rate = (int)mode->refresh_rate;
170+
if (first_rate == 0)
171+
first_rate = rate;
172+
else if (rate != first_rate)
173+
{
174+
mixed = true;
175+
break;
176+
}
177+
}
178+
}
179+
180+
SDL_free(displays);
181+
182+
if (mixed != multi_monitor_mixed_refresh)
183+
{
184+
multi_monitor_mixed_refresh = mixed;
185+
if (mixed)
186+
Log("Multiple monitors with different refresh rates detected");
187+
188+
if (display_is_vsync_forced_off())
189+
{
190+
SDL_GL_SetSwapInterval(0);
191+
last_vsync_state = 0;
192+
Debug("Vsync forced off: multi-viewport with mixed refresh rate monitors");
193+
}
194+
else if (config_video.sync)
195+
{
196+
display_set_vsync(true);
197+
}
198+
}
199+
}
200+
201+
bool display_is_vsync_forced_off(void)
202+
{
203+
return config_debug.debug && config_debug.multi_viewport && multi_monitor_mixed_refresh;
204+
}
205+
206+
void display_request_gl_context_recreate(void)
207+
{
208+
pending_gl_context_recreate = true;
209+
}
210+
143211
void display_recreate_gl_context(void)
144212
{
145213
ogl_renderer_destroy();
@@ -153,7 +221,7 @@ void display_recreate_gl_context(void)
153221
SDL_GL_MakeCurrent(application_sdl_window, display_gl_context);
154222
SDL_GL_DestroyContext(old_context);
155223

156-
bool enable_vsync = config_video.sync;
224+
bool enable_vsync = config_video.sync && !display_is_vsync_forced_off();
157225
SDL_GL_SetSwapInterval(0);
158226
if (enable_vsync)
159227
SDL_GL_SetSwapInterval(1);

platforms/shared/desktop/display.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ EXTERN bool display_should_run_emu_frame(void);
3737
EXTERN void display_set_vsync(bool enabled);
3838
EXTERN void display_update_frame_pacing(void);
3939
EXTERN void display_recreate_gl_context(void);
40+
EXTERN void display_request_gl_context_recreate(void);
41+
EXTERN void display_check_mixed_refresh_rates(void);
42+
EXTERN bool display_is_vsync_forced_off(void);
4043

4144
#undef DISPLAY_IMPORT
4245
#undef EXTERN

0 commit comments

Comments
 (0)