Pushed two different fixes, both seem to work. Would appreciate feedback.
The first fix is a simple workaround: modify
NSViewComponentPeer::toFront() to only bring the view to the front if it’s not already the front one. The responsiveness issue can probably still occur but much more rarely, so the issue becomes minor.
The second fix replaces
juce::WaitableEvent with a
std::condition_varaible for signalling repainting in
OpenGLContext. This eliminates the lock on notification which
juce::WaitableEvent does, which IIUC is needed to ensure robust notification of future waiters.
std::condition_variable doesn’t ensure that, and I don’t think we need that assurance here.
Why we might want the assurance of notifying future waits is in cases when the render loop isn’t keeping up, then it’s possible the
CVDisplayLink callback will make a second notification before the render loop finishes handling the first, the next frame will then only start to render on the third notification, instead of immediately when the first render finishes. So this could make cases where the render loop isn’t keeping up worse.
But, I think of more significance is that not taking a lock on notification will improve performance, possibly making previously not-keeping-up render loops keep up.
EDIT: Thinking more about this, we can probably add a similar
std::atomic<bool> triggered data member like
juce::WaitableEvent to catch missed notifications, which will work fine 99% of the time (the remaining 1% would be if we accidently reset an “extra” notification instead of the “original” one which we meant to reset. Though maybe this could be resolved by using an
std::atomic<int>? And maybe this could also be used in
juce::WaitableEvent to also remove the lock-on-notification there?)