This is currently on Mac, in a standalone application, but I think the problem probably applies to all platforms. (It is also on JUCE 4.3 – sorry; if this has been resolved in more recent versions, that would be a solution as well).
I have found that using an OpenGLContext attached to the top level component of the window improves CPU usage substantially in my app. I am not using any OpenGL calls directly, I am just using it to accelerate JUCE’s 2d Drawing.
If I create multiple windows, and each has an OpenGLContext attached to its top level component, I find that the CPU load goes way up (e.g. from 7-9% for one window open, all the way up to 60-70% with two windows open).
I profiled the app, and found that a huge amount of time was being spent in MessageManagerLock::attemptLock,
specifically in the Thread::yield() call.
I suspect that this is because each OpenGLContext creates its own ThreadPool and they are essentially spin-waiting on each other to lock the MessageManager.
If I change the OpenGLContext::renderFrame() to unconditionally lock the MessageManager, then the CPU load drops to something reasonable, but then (not unexpectedly) I get a deadlock when the system tries to tear down the ThreadPool (e.g. when closing a window).
Is there some sort of method to coordinate the rendering of the OpenGLContexts to avoid this lock contention and spin-waiting?
If not, are there any suggestions for how to essentially single-thread the renderFrame() calls for multiple OpenGLContexts?
Effectively, without some sort of support for this, multiple OpenGLContexts are not performant.