Performance issue with OpenGL in multiple windows


same issue reported to us on Windows when using OpenGL renderer


Can’t you just add it here or gist of the critical parts?


@ttg Here is a reduced code. Only the Editor class and I hope I didn’t made any mistake while rearranging some of the functions…


Bump :slight_smile:


Hi @FineCutBodies, this code currently fails under macOS at least for me.

JUCE Assertion failure in juce_AudioProcessor.cpp:360
ERROR: 0:1: '' :  version '130' is not supported

JUCE Assertion failure in juce_OpenGLShaderProgram.cpp:90

It might be simpler to use JUCE own demo as a base for reproducing the problem.
I’ll try using the Demo. p.s - we saw decrease in performance (as we add more plug-ins) even by just using the JUCE OpenGL renderer with no direct OpenGL on our code.


You may need to specify the version of OpenGL that is required before attaching as the shaders are written in GLSL 1.30.10.

m_glContext.setOpenGLVersionRequired (OpenGLContext::openGL3_2);


On Windows we also seem to be running into the issue of needless MessageManager locking.

We have a graph component that draws some EQ band handles and curves with an OpenGLRenderer drawing some spectrum analysis content behind it.

When we want to update the spectrum analyzer there’s OpenGLContext::triggerRepaint(), but because it’s attached to a component it locks the message thread to run our normal component painting (which doesn’t need to be done at a continuous 60Hz!)

Has anyone come up with a simple workaround for this, so that you can trigger only the OpenGLRenderer to update without re-painting the whole attached component? Unless I’m missing something it seems like it would take a decent amount of modification to JUCE :confused:


Seems like if you’re running into this issue, you can edit the triggerRepaint() functions of OpenGLContext and OpenGLContext::CachedImage to take a default int argument and use it to set the needsUpdate member in juce_OpenGLContext.cpp line 172.

Then if you want to update the renderers without redrawing the component you can use OpenGLContext::triggerRepaint(0)


That’s interesting, was it that the Device Context (dc in that swap buffers call) was null?


For others experiencing this problem on Windows, my troubles seemed to clear up after disabling vertical sync:


Are you sure it solved your problem or just made it less noticable? For me the problem is still there if there is no vertical sync, but then the FPS start to drop from 500FPS so I need more instances to get to the same low FPS.


Strange, for me I was able to run like 10+ instances of the plugin and still didn’t see the frame rate dropping at all. That applies to both for my example in the link (that doesn’t use component rendering, only juce::OpenGLRenderer) and our EQ plugin that does both juce::OpenGLRenderer rendering and component rendering

If it makes any difference I should note that our EQ plugin uses a timer to trigger changes in our rendering, rather than using OpenGLContext::setContinuousRepainting(true)


Where should you call it ?
In my plugin I only attach the openGLContext to my component and that’s it so I don’t see much where I should call setSwapInterval(0) for the context to be active which is mandatory.

Thanks !


@otristan based on the implementation of juce::OpenGLContext, the attachment only seems to be active after the component is showing and has a valid size

I believe after those requirements are met you can use juce::OpenGLContext::makeActive() and then use setSwapInterval(). It feels a bit cumbersome but without juce::OpenGLRenderer you don’t seem to get equivalent functions for newOpenGLContextCreated() and openGLContextClosing()

Also, the swap interval defaults to 1 when the context is initialized, so setSwapInterval() needs to be called after an attachment is made/reset (for example, when the attached component’s visibility changes the attachment is removed until it’s made visible again)


Tried that but had some error.
@Juce Any comments on this ?

Thanks !


Yeah, that would be great if somebody from Juce could weight in, as it seems like a bug for me. @fabian ?


Bumping this. We are experiencing this in our newest product, BYOME, and are receiving a lot of support emails about it.


Yeah it would be great to at least know if a solution is within reach or if it would require a huge overhaul. Our next product will start testing soon and relies on GL. Any info or a suggested workaround that we could implement would be much appreciated.


I can confirm it, you have the same issue. Just checked the framerate of Byome with Fraps and it gives about 55-60 fps for one instance, then drops to 30 with 2 and to about 20 with 3… then Ableton stopped working, so had to shut it down.


Any JUCE people to investigate this ?

Thanks !

Multiple DocumentWindows with GL contexts

I’m looking into it now, but I can’t see an easy fix…