Call Component methods inside OpenGL render?

Hi everyone,

I see in the OpenGL examples methods are called such as getWidth() and getHeight() from within the OpenGL render. Is this guaranteed to be thread safe?
The OpenGL render thread does sometimes lock the main-thread, but now always, what’s the logic behind this?

If I am allowed to call getWidth(), getHeight(), does it mean I can call any main thread function from OpenGl render or just some Component methods?

I know there are already some topics about this subject but I couldn’t find a clear answer.

Thanks,
Jelle

Can someone comment on this?

What cases are there where the message manager is not locked? Looking at juce_OpenGLContext.cpp it seems to acquire a lock in renderFrame() before the renderer’s renderOpenGL method is called:

Looks like it’s not locked however for the newOpenGLContextCreated() and openGLContextClosing() methods.

So every render I print whether the main thread is locked and that looks like
not locked
locked
not locked
locked
locked
not locked
locked
not locked
locked
not locked
locked

Not very deterministic.
My question comes from the fact that JUCE example code calls main thread functions like getWidth() or findColour in the openGl render and it made me wonder whether this is thread safe. If not, the JUCE example code should better change.

If the message thread is locked, those methods will be safe to call.

If you’re just calling getters, 99% of the time you’ll be fine even if the thread isn’t locked, but there’s still that 1% chance that as you read the width of your component, something else is updating the component’s bounds.

I would do some investigation into why the thread isn’t locked. Put a break point in your render method when it’s not locked and look up through the callstack.

You’re not calling render manually anywhere are you?

I’m not calling render manually.

I’ve looked into the stack and it looks as if main thread is locked if normal juce components like buttons, sliders need to be repainted. The main thread must be locked in the normal paint() routine, that’s why. The isUpdating flag is set if such components need repainting.

So far my conclusion is that I cannot rely on the main thread being locked so will have to implement my own thread synchronisation.

You could just lock the thread yourself before calling the component methods. Or, listen to changes in the component on the message thread and update some atomics for any values you need to use on the render thread.

1 Like

I’m not sure if locking the main thread is safe or efficient.
Thank you for your help @ImJimmi