OpenGL Deadlock when using Multiple OpenGLRenderers on Linux

I’m using components following this tutorial, which inherit from juce::OpenGLRenderer and contain a juce::OpenGLContext, which they attach to themselves. When using a single instance of this type of component, everything works fine. When using multiple of these components, I get deadlocks in XWindowSystemUtilities::ScopedXLock xLock when doing one of the following:

  • calling Component::setVisible(false);
  • closing the GUI

Do I have to somehow separate them better? I read about viewports in OpenGL, perhaps I need to make the entire Canvas an openGLcontext and then make the individual components viewports? Just groping in the dark here…

Attached is a pic of the call stack during the lock when closing the GUI:

Use one context and change viewports, like you suggest. I was getting a swap-buffer hang when I tried multiple contexts on Mac, don’t know about Linux, but it sounds very familiar.

1 Like

Thanks for your answer!

Could you shed some light on how this is done? I just gave it a quick spin, but the problem is that my individual components are the OpenGLRenderers themselves. I added a single openGLContext to the PluginEditor, and pass it into the children to be used there.

Now at some point I have to call:

m_openGL_context.setRenderer(this);
m_openGL_context.attachTo(*this);

To set the component being drawn, as well as the openGLRenderer. If I do this for both my Components, only the last one will get drawn.

So I will have to make the renderer the PluginEditor as well, and from within its renderOpenGL() set the component to attach and then call its rendering function myself? Kinda like this:

PluginEditor::renderOpenGL() {
  m_openGL_context.attachTo(foo);
  foo.renderSomeStuffInViewPort();

  m_openGL_context.attachTo(bar);
  bar.renderSomeStuffInViewPort();
}

This sounds like it could be a JUCE bug. Are you able to provide a minimal code example that demonstrates the problem?

HI @reuk

I’ve made this repo, which demonstrates the problem:

Please keep in mind that on Linux with NVidia Gtx Cards, you will have to run nvidia-settings first and disable Sync to VBlank in OpenGL Settings. Otherwise the entire application will be laggy af.

1 Like

Ok I got it working finally with awesome extra benefits: Apart from only rendering the OpenGL stuff in a single context, now the entire GUI is being rendered with the help of OpenGL. Meaning: even the standard juce::Graphics draw calls are so much faster now.

For any future lost traveller here’s what to do:

Add the juce::OpenGLContext to your PluginEditor. Also make it inherit from juce::OpenGLRenderer, like in the tutorial I posted in my first post. Now in your renderOpenGL call, call a custom rendering function from the sub-components you want to draw. To crop the content to this component, set up a viewport like so:

const auto desktopScale = (float)m_openGL.getRenderingScale();
const auto viewport_origin = juce::Point<int>(0, getTopLevelComponent()->getHeight() - getHeight()) +
	                             getLocalPoint(getTopLevelComponent(), juce::Point<int>());

glViewport(-viewport_origin.getX(),
	           viewport_origin.getY(),
	           juce::roundToInt((float)getWidth() * desktopScale),
	           juce::roundToInt((float)getHeight() * desktopScale));

Also keep in mind that if you’ve used GL_ENABLE(GL_SCISSOR_TEST), you will have to adjust your scissor bounds to the component as well, as it is not carried over by the viewport.
The same goes for clearing the screen (always clears everything).

A last caveat I have now is that all components in the PluginEditor are drawn ontop of the openGLContext, but there’s probably a solution for this.

1 Like

I just tried this out with current develop on Ubuntu 18.04 with the default desktop, and 20.04 with both XFCE and the default desktop. I didn’t see any deadlocks when closing the standalone app. I think the deadlocks might also be hardware-dependent (I’m testing in VMWare Fusion on a macbook pro).

BTW, I got a big speed up using one renderer, and multiple viewport changes, on both MacOS and Windows.
/edit/ perhaps not as much on Windows as I hadn’t noticed much slowdown to start with. I think it’s definitely the way to go until OpenGL goes in the bin forever…