[MacOS] Vsync has issues on MacOS
Regardless of renderer settings MacOS seems to always have VSync enabled. I have tried not calling it at all as well as:
SDL_SetRenderVSync(engine.renderer, 0); SDL_SetRenderVSync(engine.renderer, SDL_RENDERER_VSYNC_DISABLED);
I checked this by moving the window to a monitor set to 60hz and the framerate immediately dropped to target 60fps.
In case it matters. I was testing this on an M2 Mac Studio.
Someday we'll go a full year without vsync breaking on the Mac again. :)
Putting this in 3.2.2 for investigation.
There is something a bit screwy with Mac sync in general I think. If you enable the graphics monitor, it will slow down, speed up, seemingly at random...
https://github.com/user-attachments/assets/915efab4-2836-4413-8f5c-bd638c692dc0
I get similar behaviour to Thrud on my MacBook Air M2 (60Hz display) running MacOS Sonoma 14.6.1 (pre-ProMotion).
My project uses SDL_AppIterate.
Enabled
When VSync is enabled (SDL_SetRenderVSync(ren, 1)), it seems to work as expected. MTL_HUD_ENABLED=1 shows a steady 60Hz.
My own measurements (based on SDL_GetTicksNS()) also show an average 60Hz (although the steadiness can vary).
Not Enabled
When VSync is not enabled, the frame rate seems to jump between "as fast as possible" and 60Hz.
It will switch seemingly at random, but there are some things that reliably drop the frame rate to 60Hz for a little while. Grabbing the window by the title bar and shaking it. Playing a video in VLC.
In both screenshots, the area in orange is when I am moving the window around with the mouse.
I have same issue. Very simple test program:
Not touching any vsync setting, RenderPresent will wait for vsync. Even setting VSYNC disabled (as below) RenderPresent will wait for vsync.
SDL_Window *window = SDL_CreateWindow("DisplayPP Test Harness", 1120, 768, SDL_WINDOW_RESIZABLE);
SDL_Renderer *renderer = SDL_CreateRenderer(window, NULL);
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, 560, 192);
if (!SDL_SetRenderVSync(renderer, SDL_RENDERER_VSYNC_DISABLED)) {
for (int i = 0; i < 300; i++) {
SDL_Event event;
SDL_PollEvent(&event);
if (event.type == SDL_EVENT_QUIT) {
return 0;
}
start = SDL_GetTicksNS();
SDL_RenderClear(renderer);
SDL_RenderTexture(renderer, texture, &srcrect, &dstrect);
SDL_RenderPresent(renderer);
end = SDL_GetTicksNS();
cumulative += (end-start);
times[i] = (end-start);
}
the ticks will reliably be in the 13ms range (I have 75hz monitors).
(This might bump to a later milestone.)
It will switch seemingly at random, but there are some things that reliably drop the frame rate to 60Hz for a little while. Grabbing the window by the title bar and shaking it. Playing a video in VLC.
Fwiw, this specific thing sounds like the system compositor taking control, and we're unlikely to be able to avoid that.