How to disable vsync on macOS
Asked Answered
R

3

15

With all my SDL/OpenGL programs, the framerate is stuck at 60fps, so looks like the vsync is enable, but not by me, nor in my code or my settings. so i would like to now if there is a way to disable it, maybe in some deep macOS settings?

Realpolitik answered 10/9, 2012 at 5:18 Comment(0)
R
5

After YEARS looking for a workaround (and with the help of Brett Hale) this is what worked for me - I've added that piece of code at the start of my render loop (and not only in the init, as Apple seems to reset the SwapInterval settings every time...) and was finally able to have unsynchronize framerate:

#ifdef __APPLE__
GLint                       sync = 0;
CGLContextObj               ctx = CGLGetCurrentContext();

CGLSetParameter(ctx, kCGLCPSwapInterval, &sync);
#endif

Don't forget to include <OpenGL/gl.h>

It's not the nicest solution but it's actually the only one I found that work like a charm.

Realpolitik answered 12/9, 2016 at 20:26 Comment(8)
Apparently this is broken in Mac OS 10.14 (Mojave), with vsync always disabled, (but vsync in Metal still works). SDL2.0.10+ (not yet released) will work around this bug by using CVDisplayLink instead. You can see the commit here and discussion hereTayyebeb
Also, the code SDL2 were previously using only seems to set this once, not every frame. Maybe because they instead called [NSOpenGLContext setValues:&value forParameter:NSOpenGLCPSwapInterval]Tayyebeb
News just in, apparently OpenGL vsync is fixed in the next release, Mac OS 10.14.4Tayyebeb
Confirmed working on macOS 10.14, but seems this is not working on macOS 10.15 and 11 anymore, I've tried kCGLCPSwapInterval / NSOpenGLCPSwapInterval / CVDisplayLinkThermomagnetic
Found out on macOS 10.15 and 11, the actual drawing code including flushBuffer() must not be put in func draw(_ dirtyRect: NSRect)Thermomagnetic
May be a simple question, but where do I execute this code and how? I tried in in Terminal and I have Xcode.Capstone
I followed the instructions here: reddit.com/r/applehelp/comments/5bb0db/… with the above code however several errors were thrown. Scouring GitHub it seems there is a problem with disabling VSync in Mac OS 12.2.Capstone
@MustafaIqbal this code goes inside your render loop when developing your app (I was using c++). Note that it will only affect your app, it's not a shared settingRealpolitik
R
9

This enabled me to get around ~700 frames per second on my MacBook Pro.

It is not permanent either, perfect for testing/benchmarking.

Source

Renata answered 5/9, 2014 at 4:14 Comment(5)
Oh my gad, after all that time!! Thanks so much mate!Realpolitik
i tried this and nothing happened. What am i doing wrong?Hephzibah
1. Double check that the app you are testing can actually go over 60fps; 2. This solution was for Mavericks 10.9, untested for Yosemite or El CapitanRenata
Would you mind to state in your answer that this solution is actually not working on 10.11 with xCode 7.3 (that the only one I've tried) anymore please?Realpolitik
Your first link is broken: it says Your session has expired. Please log in..Chunchung
V
5

Welcome to SO. I outlined an approach here for a similar question. You should consider that most Mac LCDs are locked to 60Hz, and more recent hardware is limited to 120Hz. Disabling vsync may simply result in wasted CPU/GPU cycles, and possibly introduce tearing artifacts.

Vortumnus answered 10/9, 2012 at 7:52 Comment(1)
Yeah, i've stop looking around to find a solution... Thanks anyway!Realpolitik
R
5

After YEARS looking for a workaround (and with the help of Brett Hale) this is what worked for me - I've added that piece of code at the start of my render loop (and not only in the init, as Apple seems to reset the SwapInterval settings every time...) and was finally able to have unsynchronize framerate:

#ifdef __APPLE__
GLint                       sync = 0;
CGLContextObj               ctx = CGLGetCurrentContext();

CGLSetParameter(ctx, kCGLCPSwapInterval, &sync);
#endif

Don't forget to include <OpenGL/gl.h>

It's not the nicest solution but it's actually the only one I found that work like a charm.

Realpolitik answered 12/9, 2016 at 20:26 Comment(8)
Apparently this is broken in Mac OS 10.14 (Mojave), with vsync always disabled, (but vsync in Metal still works). SDL2.0.10+ (not yet released) will work around this bug by using CVDisplayLink instead. You can see the commit here and discussion hereTayyebeb
Also, the code SDL2 were previously using only seems to set this once, not every frame. Maybe because they instead called [NSOpenGLContext setValues:&value forParameter:NSOpenGLCPSwapInterval]Tayyebeb
News just in, apparently OpenGL vsync is fixed in the next release, Mac OS 10.14.4Tayyebeb
Confirmed working on macOS 10.14, but seems this is not working on macOS 10.15 and 11 anymore, I've tried kCGLCPSwapInterval / NSOpenGLCPSwapInterval / CVDisplayLinkThermomagnetic
Found out on macOS 10.15 and 11, the actual drawing code including flushBuffer() must not be put in func draw(_ dirtyRect: NSRect)Thermomagnetic
May be a simple question, but where do I execute this code and how? I tried in in Terminal and I have Xcode.Capstone
I followed the instructions here: reddit.com/r/applehelp/comments/5bb0db/… with the above code however several errors were thrown. Scouring GitHub it seems there is a problem with disabling VSync in Mac OS 12.2.Capstone
@MustafaIqbal this code goes inside your render loop when developing your app (I was using c++). Note that it will only affect your app, it's not a shared settingRealpolitik

© 2022 - 2024 — McMap. All rights reserved.