OpenGL Swap Interval - MacOS

Yeah, that’s what I see on macOS too. Using the CVDisplayLink as suggested by @yairadix above does fix this problem and the rate is then correctly limited to the display’s vertical refresh.

Hopefully the JUCE team will implement that change.

A temporary ‘hack’ to limit the frame rate approximately without changing any JUCE code is to use the OpenGLContext::executeOnGLThread() method to call Thread::sleep() for an appropriate amount of time (based on how long since the last renderOpenGL() callback was received). Using that method means that the sleep happens before the message manager lock is acquired in renderFrame(), which is important.

Basically, the idea is for each time renderOpenGL() is called, measure the time taken since the last call, work out how much longer it needs to take, and call executeOnGLThread() with a lambda containing a sleep() for that time.

This method is by no means perfect, because the frame rate isn’t absolutely consistent, but for now, that’s provided a massive improvement in terms of being able to have multiple GUI instances open without hogging the message thread.

Again, IMO the ideal solution would be for JUCE to use the CVDisplayLink to ensure a consistent v-sync frame rate.

4 Likes