SDL icon indicating copy to clipboard operation
SDL copied to clipboard

[MacOS] Vsync has issues on MacOS

Open NitroPlum opened this issue 1 year ago • 8 comments

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.

NitroPlum avatar Jan 25 '25 22:01 NitroPlum

In case it matters. I was testing this on an M2 Mac Studio.

NitroPlum avatar Jan 25 '25 23:01 NitroPlum

Someday we'll go a full year without vsync breaking on the Mac again. :)

icculus avatar Jan 26 '25 06:01 icculus

Putting this in 3.2.2 for investigation.

icculus avatar Jan 26 '25 06:01 icculus

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

ThrudTheBarbarian avatar Feb 09 '25 18:02 ThrudTheBarbarian

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).

VSync Enabled

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.

VSync Not Enabled

In both screenshots, the area in orange is when I am moving the window around with the mouse.

weslord avatar Jun 05 '25 21:06 weslord

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).

jawaidbazyar2 avatar Jun 18 '25 22:06 jawaidbazyar2

(This might bump to a later milestone.)

icculus avatar Oct 08 '25 17:10 icculus

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.

icculus avatar Nov 10 '25 20:11 icculus