Rendering multiple instances of a plugin with OpenGL

I have a problem concerning OpenGL rendering performance in JUCE. 
Everything works fine as long as I have at most one editor open. When I open multiple instances of the plugin, I can see the performance drop significantly. 
Of course this can be expected to a certain point, but I think a lot of time is wasted due to synchronization. 
Profiling showed that about 50% of the runtime is spent on getting the MessageManagerLock in the method juce::OpenGLContext::CachedImage::renderFrame() when showing 8 editors. 
Is it really necessary to hold a lock that essentially serializes all rendering operations of the different plugin instances? 
I assumed that threaded access to OpenGL should be possible if each instance has its own context. 
 

1 Like

If you're not using any of the juce 2D rendering functionality in your contexts, then yes, they can all run freely on threads, but if you've got your juce paint() methods rendering using GL then it does need to synchronise each one, as they all need to play nicely with the message thread.

Thanks for the heads-up though, we've not tested the performance of multiple instances and there could be something we can optimise. Will make a note to investigate..

Is there any news for this issue?

We have the same serious problem (tested on Windows-Systems). Currently we’re evaluating to port our plug-ins to JUCE. The none-JUCE plug-ins currently updating the UI approx. 30 times per second to display VU, gain and spectral data. This all works very smooth even for multiple instances.
In JUCE we now have done the same using a timer in which we update the controls with a repaint call. The UI is rendered using OpenGL and the normal JUCE’s paint methods of the components.
We installed openGL in the editor like follows:

// use openGL rendering
m_glContext.setMultisamplingEnabled(false);
m_glContext.attachTo(*this);
m_glContext.setContinuousRepainting(false);
if (ComponentPeer* peer = getPeer())
  peer->setCurrentRenderingEngine(0);

This all work very well, fast and smooth.
BUT if we load another instance of the plug-in, the UI thread gets nearly blocked, loading a third plugin-instance will completely block the whole application (using a high-end GPU).
Interestingly, it’s not important how much components are redrawn. Simply the fact that the timer calls a repaint regularly will produce the problem.

Our current solution is to have an “Editor-Instance-Counter” and reduce the repaint-calls by the factor of this counter…
This is a solution, but it’s not nice, because using 3 instances the UI update rate is very slow for each instance (with OpenGL hardware rendering is used!) - How we should tell the customers? :wink:

Another solution could be to support a kind of “idle”-message/call which is called regularly but only if there’s enough UI time… I think the JUCE-timer is a very enforced way of updating…

So my question is:

  • Is there any work scheduled to solve this message-blocking problem using multiple-instances with openGL? Is it really necessary to have the message-manager as a DLL singleton?
  • Is there any possibility to listen to an idle-message in an audio-plugin (like it’s supported in VST) ?

Cheers,
Frank.

2 Likes