OpenGLComponent deleting context

[quote=“X-Ryl669”]I don’t get the issue you’re encoutering. I’m doing all the OGL rendering in a thread, and never encountered any issue with both Linux and Windows.
The only thing I could think of, is to actually create the first context on the message thread, since if you avoid this, it breaks on Windows.[/quote]

My linux limitations may have been due to the fact that you need the correct X view connection. That changed a bit (in juce) after I had the main fight with Linux threading. Nonetheless, if you render from a thread on Linux, you must create the context and do all work on the thread. I believe the XGL spec covers that.

[quote]Then, I just make sure that when the component is deleted, the thread is stopped, it’s quite easy, put a thread.stopThread() in your destructor, then you can acquire a the context for a last time (in your destructor), and perform the OGL’s deletions (like texture, and other) in that context, that is, the message thread’s stack.
I wonder why you need to start / stop the thread on visibility change, as the overhead to create a thread is a 100’d of time larger than to simply wait for an event in the main loop to avoid doing any work if not visible.[/quote]

Not sure why you’re missing this unless it’s just Mac, or how you’re threading. It’s possible right now for the ComponentWatcher to destroy the context before you get a chance to delete the context on your thread. If that’s not a problem for you, good for you, but I suspect you’re just lucky.

Does to me. It’s the context that actually does the drawing (or has it done on it), so having another class, more closely allied to the context than the Component makes more sense. Linking the two can be tricky, as you’ve found, and it seems that the rules vary.

We’ll also need:
A ‘needsReshape’ marker so the thread can cope with any size changes. That can be as simple as a shouldExit (clean up at end of thread) and then a ‘I’m done’ marker so that the main thread can do what is needed and optionally re-open the whole thing (at a new size etc). In the Mac/Win case, this would be just the thread stopping any interaction with the context, and then the main thread making it current and doing work. In the Linux case, the OpenGL clean-up would be on the thread and the window/X stuff on the main thread. In essence, everything should be two part - a main thread callback and render thread callback in each case. I just use the render thread starting and stopping for the threaded side.

Bruce

So, something like this…

[code]class OpenGLRenderer
{
public:
OpenGLRenderer() {}
virtual ~OpenGLRenderer() {}

virtual void initialiseOpenGL() = 0;
virtual void shutdownOpenGL() = 0;
virtual void openGLViewportResized (int newWidth, int newHeight) = 0;
virtual void renderOpenGL() = 0;

};[/code]

I’d have thought that these callbacks should all be guaranteed to be called by the same background thread - does that make sense, or are there things that it may need to do that can only happen on the message thread in some OSes?

I don’t know what is the X view connection, but I’m guessing it’s the Display variable you’re talking about.

No that’s not legally true. You can share contexts between threads. That said, 99% of people will do it like you said, and so do I.

Well, if you use the code without overloading the method, you’ll get the behaviour you describe.
BUT, the OpenGLContext has a virtual deleteContext() method, and your OpenGLComponent has a newOpenGLContextCreated callback for you, where you can set up a new context for your thread to shareWith().
So you can overload the OpenGLContext with your ThreadOpenGLContext, and when the OGLComponent create its message thread’s context, you’ll create your own in your thread, and set up to share with it. You’ll be informed about the deletion in the deleteContext method, so you can do whatever you want.
That said, having a accessible way to overload the main context creation / destruction could be interesting too.

Sounds like we’re in agreement about the way to go, but for reference:

The OpenGLComponent callback - good. There I can do work. Overriding the OpenGLContext delete, and then trying to backtrack and work out which openGLComponent it was, whether it was my subclass or not, then asking it to do the correct clean-up work - bad, in my book. It’s an OOP nightmare, and that’s completely aside from multi-threading considerations (is the context currently rendering? Will that thread get blocked while I’m trying to do something?).

The best thing - I’m hearing that between Jules and us lot we can soup up the Juce OpenGL component code enough that hardly any extra overrides are needed, and they will crank out some awesome frame-rates with hardly any work!

Bruce

I guess it’s time. Jules, unless you have refactored the OGL class, I’m going to have a go using an ‘isThreaded()’ switch system, hopefully in the same component. There are a few things that I need to set with bools across threads (contextShouldReposition() for example). What would you prefer? An atomic int with 0 and 1 or a bool and a CriticalSection?

There should only be two or three of them.

I was going to do it as diffs off the current head so you can make a branch and test it?

Bruce

Sounds great, Bruce! For cross-thread bools, I’d recommend an Atomic if possible.