Rendering in thread other than main

Hi everyone!

In my application, I am splitting the event handling and OGL rendering part
into two threads:
The event handling is done in the main thread, while all of the rendering
goes
in a secondary one.
Right now, I am creating the window in the main thread, passing it to the
render thread,
and then the render thread creates the context / does it’s rendering etc.

I couldn’t really find anything on the net (other than a few docs that
mostly said
"just don’t do it", but I’m sure it shouldn’t be that hard to cleanly split
those two areas
into threads, right? With Valve even doing rendering from multiple threads
and stuff.
So, my question is, is this approach of mine correct and will it work on
other desktop
platforms? So far, I’ve only tested it on Linux, where it works without any
troubles.

Thanks,
Jonas

They’re not actually “rendering” from multiple threads, just spreading
the CPU work (such as culling) across multiple cores. The GL calls are
still single-threaded.On 30.07.2013 03:25, Jonas Kulla wrote:

With Valve even doing rendering from multiple threads and stuff.

Hi everyone!

In my application, I am splitting the event handling and OGL rendering part into two threads:
The event handling is done in the main thread, while all of the rendering goes
in a secondary one.
Right now, I am creating the window in the main thread, passing it to the render thread,
and then the render thread creates the context / does it’s rendering etc.

I suspect this won’t work on Windows.

I have previously used threads OK with X11. In particular a separate thread read SDL
events and sent them to the main thread via some code I wrote. This worked fine
on Linux. It did NOT work on Windows ;(On 30/07/2013, at 11:25 AM, Jonas Kulla wrote:


john skaller
@john_skaller
http://felix-lang.org

Windows demands the window procedure to be called in the same thread
that created the window. This means processing the events in that
thread (since that’s when it’s called). OpenGL rendering may be done
in a different thread if the context is given to that thread though
(remember you can use wglMakeCurrent to set the OpenGL context of a
thread).

Still, doesn’t make it any safer in other OSes…

2013/7/30, john skaller :>

On 30/07/2013, at 11:25 AM, Jonas Kulla wrote:

Hi everyone!

In my application, I am splitting the event handling and OGL rendering
part into two threads:
The event handling is done in the main thread, while all of the rendering
goes
in a secondary one.
Right now, I am creating the window in the main thread, passing it to the
render thread,
and then the render thread creates the context / does it’s rendering etc.

I suspect this won’t work on Windows.

I have previously used threads OK with X11. In particular a separate thread
read SDL
events and sent them to the main thread via some code I wrote. This worked
fine
on Linux. It did NOT work on Windows ;(


john skaller
skaller at users.sourceforge.net
http://felix-lang.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Wouldn’t it be easier to keep the rendering part on your main thread and
move the rest of your logic to a different one?On Tue, Jul 30, 2013 at 8:28 PM, Sik the hedgehog < sik.the.hedgehog at gmail.com> wrote:

Windows demands the window procedure to be called in the same thread
that created the window. This means processing the events in that
thread (since that’s when it’s called). OpenGL rendering may be done
in a different thread if the context is given to that thread though
(remember you can use wglMakeCurrent to set the OpenGL context of a
thread).

Still, doesn’t make it any safer in other OSes…

2013/7/30, john skaller :

On 30/07/2013, at 11:25 AM, Jonas Kulla wrote:

Hi everyone!

In my application, I am splitting the event handling and OGL rendering
part into two threads:
The event handling is done in the main thread, while all of the
rendering

goes
in a secondary one.
Right now, I am creating the window in the main thread, passing it to
the

render thread,
and then the render thread creates the context / does it’s rendering
etc.

I suspect this won’t work on Windows.

I have previously used threads OK with X11. In particular a separate
thread
read SDL
events and sent them to the main thread via some code I wrote. This
worked
fine
on Linux. It did NOT work on Windows ;(


john skaller
skaller at users.sourceforge.net
http://felix-lang.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

2013/7/31 john skaller

Hi everyone!

In my application, I am splitting the event handling and OGL rendering
part into two threads:
The event handling is done in the main thread, while all of the
rendering goes
in a secondary one.
Right now, I am creating the window in the main thread, passing it to
the render thread,
and then the render thread creates the context / does it’s rendering etc.

I suspect this won’t work on Windows.

I have previously used threads OK with X11. In particular a separate
thread read SDL
events and sent them to the main thread via some code I wrote. This worked
fine
on Linux. It did NOT work on Windows ;(

Yeah… X11 is pretty hard to crack in terms of doing threaded stuff. As
long as I call XInitThreads(),
I was able to do event processing / rendering in different threads without
problems.

In my current case as I’ve described, I do the event reading in the main
thread.> On 30/07/2013, at 11:25 AM, Jonas Kulla wrote:

2013/7/31 Sik the hedgehog <sik.the.hedgehog at gmail.com>

Windows demands the window procedure to be called in the same thread
that created the window. This means processing the events in that
thread (since that’s when it’s called). OpenGL rendering may be done
in a different thread if the context is given to that thread though
(remember you can use wglMakeCurrent to set the OpenGL context of a
thread).

Still, doesn’t make it any safer in other OSes…

2013/7/30, john skaller :

Hi everyone!

In my application, I am splitting the event handling and OGL rendering
part into two threads:
The event handling is done in the main thread, while all of the
rendering

goes
in a secondary one.
Right now, I am creating the window in the main thread, passing it to
the

render thread,
and then the render thread creates the context / does it’s rendering
etc.

I suspect this won’t work on Windows.

I have previously used threads OK with X11. In particular a separate
thread
read SDL
events and sent them to the main thread via some code I wrote. This
worked
fine
on Linux. It did NOT work on Windows ;(

Yes. I originally oriented myself by OSX though (as Windows is my least
priority
right now), where it is strictly forbidden/impossible to do event reading
in anything
other than the main thread. This is why I specifically put the event code
there, and
the render loop into a separate one. I don’t even pass a context to this
thread, only
the window handle. The render thread is responsible for context
creation/destruction
itself. I speculated this would allow me to skip the whole "makeCurrent()"
shenanigans.> > On 30/07/2013, at 11:25 AM, Jonas Kulla wrote:

2013/7/31 Iv?n Vodopiviz

Wouldn’t it be easier to keep the rendering part on your main thread and
move the rest of your logic to a different one?

Windows demands the window procedure to be called in the same thread
that created the window. This means processing the events in that
thread (since that’s when it’s called). OpenGL rendering may be done
in a different thread if the context is given to that thread though
(remember you can use wglMakeCurrent to set the OpenGL context of a
thread).

Still, doesn’t make it any safer in other OSes…

2013/7/30, john skaller :

Hi everyone!

In my application, I am splitting the event handling and OGL rendering
part into two threads:
The event handling is done in the main thread, while all of the
rendering

goes
in a secondary one.
Right now, I am creating the window in the main thread, passing it to
the

render thread,
and then the render thread creates the context / does it’s rendering
etc.

I suspect this won’t work on Windows.

I have previously used threads OK with X11. In particular a separate
thread
read SDL
events and sent them to the main thread via some code I wrote. This
worked
fine
on Linux. It did NOT work on Windows ;(

So, you mean doing both event handling and rendering on the main thread,
any anything else in a separate thread?
This would make things reeeeally complicated as I’d basically have to
reinvent GLX to pass my render commands to the main thread =(> On Tue, Jul 30, 2013 at 8:28 PM, Sik the hedgehog < sik.the.hedgehog at gmail.com> wrote:

On 30/07/2013, at 11:25 AM, Jonas Kulla wrote:

So, you mean doing both event handling and rendering on the main thread,
any anything else in a separate thread?
This would make things reeeeally complicated as I’d basically have to
reinvent GLX to pass my render commands to the main thread =(

It’s only complicated if you use a low level language like C.On 31/07/2013, at 9:58 AM, Jonas Kulla wrote:


john skaller
@john_skaller
http://felix-lang.org

So, you mean doing both event handling and rendering on the main thread,
any anything else in a separate thread?
This would make things reeeeally complicated as I’d basically have to
reinvent GLX to pass my render commands to the main thread =(

It’s only complicated if you use a low level language like C.On 31/07/2013, at 9:58 AM, Jonas Kulla wrote:


john skaller
@john_skaller
http://felix-lang.org

If you want to stick with C, you could look at using the “blocks” extension from clang: http://clang.llvm.org/docs/BlockLanguageSpec.html

That way you can pass code directly.

On 31/07/2013, at 9:58 AM, Jonas Kulla wrote:

So, you mean doing both event handling and rendering on the main thread,
any anything else in a separate thread?
This would make things reeeeally complicated as I’d basically have to
reinvent GLX to pass my render commands to the main thread =(

It’s only complicated if you use a low level language like C.


john skaller
skaller at users.sourceforge.net
http://felix-lang.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

2013/7/31 Jorgen Tjerno

If you want to stick with C, you could look at using the "blocks"
extension from clang: http://clang.llvm.org/docs/BlockLanguageSpec.html

That way you can pass code directly.

  • J?rgen.

behalf of john skaller [skaller at users.sourceforge.net]

So, you mean doing both event handling and rendering on the main thread,
any anything else in a separate thread?
This would make things reeeeally complicated as I’d basically have to
reinvent GLX to pass my render commands to the main thread =(

It’s only complicated if you use a low level language like C.

Er… I feel like there was a misunderstanding. The part about
"reimplementing GLX"
was a joke to illustrate how ridiculous of an effort it would be for a
problem that probably
does not even exist. I’m sticking to threads.

This OSX manual [1] doesn’t mention anywhere that OpenGL rendering is
restricted
to only the main thread. I’m not too interested in Windows, but I couldn’t
find anything
contrary to my design either. In fact, this blog post [2] says it’s just
fine as long as I
get a DC from the main thread window (which I hope SDL does under the hood
for me
with SDL_GL_CreateContext).

So I just have a last question: Does SDL_GL_CreateContext implicitly call
SDL_GL_MakeCurrent?

Thanks everyone who tried to help me so far =D

[1]
https://developer.apple.com/library/mac/#documentation/graphicsimaging/conceptual/opengl-macprogguide/opengl_threading/opengl_threading.html
[2]

Jonas> From: sdl-bounces at lists.libsdl.org [sdl-bounces at lists.libsdl.org] on

Sent: Wednesday, July 31, 2013 4:44 AM
To: SDL Development List
Subject: Re: [SDL] Rendering in thread other than main
On 31/07/2013, at 9:58 AM, Jonas Kulla wrote:

If you want to stick with C, you could look at using the “blocks” extension from clang: http://clang.llvm.org/docs/BlockLanguageSpec.html

That way you can pass code directly.

There are two problems with this:

(1) It isn’t C any more (will it work with MSVC++?)
(2) Memory management

C++11 has a similar feature, so if you want to stick with C you should
just use C++11 instead (since that compiles most C as written).

However it too has a memory management issue.

A much better solution “if you want to stick with C” is to use Felix
which is a C++ code generator and specifically designed to mix with
C and C++ code. Felix provides a garbage collector so that gets
rid of the memory management problem.

If you’re willing to get rid of C you can also try the Ocaml binding,
however Ocaml doesn’t support native concurrent operation.On 01/08/2013, at 5:08 AM, Jorgen Tjerno wrote:


john skaller
@john_skaller
http://felix-lang.org

Quoth john skaller , on 2013-08-01 07:25:36 +1000:

A much better solution “if you want to stick with C” is to use Felix
which is a C++ code generator and specifically designed to mix with
C and C++ code. Felix provides a garbage collector so that gets
rid of the memory management problem.

I’m really starting to get tired of seeing your advertisement every time
someone suggests that certain implementation strategies don’t work well with
their language of choice. I’m also really tired of the pseudo-objectivity
(“merely observing” (instead of claiming) that something is “better” and
plowing through who knows how many value system differences and practical
obstacles along the way).

Please stop.

—> Drake Wilson

Yes, CreateContext implicitly does a MakeCurrent - but you can just make it current on another thread afterwards. I don’t think there’s any reason you can’t CreateContext on another thread, though.

  • J?rgen.________________________________
    From: sdl-bounces@lists.libsdl.org [sdl-bounces at lists.libsdl.org] on behalf of Jonas Kulla [nyocurio at gmail.com]
    Sent: Wednesday, July 31, 2013 1:59 PM
    To: SDL Development List
    Subject: Re: [SDL] Rendering in thread other than main

2013/7/31 Jorgen Tjerno <@Jorgen_Tjernomailto:Jorgen_Tjerno>
If you want to stick with C, you could look at using the “blocks” extension from clang: http://clang.llvm.org/docs/BlockLanguageSpec.html

That way you can pass code directly.

  • J?rgen.

From: sdl-bounces@lists.libsdl.org<mailto:sdl-bounces at lists.libsdl.org> [sdl-bounces at lists.libsdl.org<mailto:sdl-bounces at lists.libsdl.org>] on behalf of john skaller [skaller at users.sourceforge.net<mailto:skaller at users.sourceforge.net>]
Sent: Wednesday, July 31, 2013 4:44 AM
To: SDL Development List
Subject: Re: [SDL] Rendering in thread other than main

On 31/07/2013, at 9:58 AM, Jonas Kulla wrote:

So, you mean doing both event handling and rendering on the main thread,
any anything else in a separate thread?
This would make things reeeeally complicated as I’d basically have to
reinvent GLX to pass my render commands to the main thread =(

It’s only complicated if you use a low level language like C.

Er… I feel like there was a misunderstanding. The part about "reimplementing GLX"
was a joke to illustrate how ridiculous of an effort it would be for a problem that probably
does not even exist. I’m sticking to threads.

This OSX manual [1] doesn’t mention anywhere that OpenGL rendering is restricted
to only the main thread. I’m not too interested in Windows, but I couldn’t find anything
contrary to my design either. In fact, this blog post [2] says it’s just fine as long as I
get a DC from the main thread window (which I hope SDL does under the hood for me
with SDL_GL_CreateContext).

So I just have a last question: Does SDL_GL_CreateContext implicitly call
SDL_GL_MakeCurrent?

Thanks everyone who tried to help me so far =D

[1] https://developer.apple.com/library/mac/#documentation/graphicsimaging/conceptual/opengl-macprogguide/opengl_threading/opengl_threading.html
[2] http://hacksoflife.blogspot.de/2008/02/creating-opengl-objects-in-second.html

Jonas

Message-ID:
<3B73B142-BEBD-403B-A633-6D3FFF1F27DB at users.sourceforge.net>
Content-Type: text/plain; charset=us-ascii

Hi everyone!

In my application, I am splitting the event handling and OGL rendering
part into two threads:
The event handling is done in the main thread, while all of the rendering
goes
in a secondary one.
Right now, I am creating the window in the main thread, passing it to the
render thread,
and then the render thread creates the context / does it’s rendering etc.

I suspect this won’t work on Windows.

I have previously used threads OK with X11. In particular a separate thread
read SDL
events and sent them to the main thread via some code I wrote. This worked
fine
on Linux. It did NOT work on Windows ;(

Could be worse. Windows allows some sort of multi-threaded window
handling (at least the last time I read about it). In contrast, OSX
apparently pauses the calling thread, sticks the info into a queue or
something, and executes the graphics call on the main thread the next
time it calls into the OS. The real doozy is iOS: everything has to be
in the main thread.

So yeah, once you leave networking protocols like X11 everything takes
a nose-dive.> Date: Wed, 31 Jul 2013 09:19:20 +1000

From: john skaller
To: SDL Development List
Subject: Re: [SDL] Rendering in thread other than main
On 30/07/2013, at 11:25 AM, Jonas Kulla wrote:

2013/8/1 Jorgen Tjerno

Yes, CreateContext implicitly does a MakeCurrent - but you can just make
it current on another thread afterwards. I don’t think there’s any reason
you can’t CreateContext on another thread, though.

  • J?rgen.

Alright, good to know! I don’t really need to make it current in another
thread, as only one thread ever renders.

2013/8/1 Jared Maddox > > Date: Wed, 31 Jul 2013 09:19:20 +1000

From: john skaller
To: SDL Development List
Subject: Re: [SDL] Rendering in thread other than main
Message-ID:
<3B73B142-BEBD-403B-A633-6D3FFF1F27DB at users.sourceforge.net>
Content-Type: text/plain; charset=us-ascii

On 30/07/2013, at 11:25 AM, Jonas Kulla wrote:

Hi everyone!

In my application, I am splitting the event handling and OGL rendering
part into two threads:
The event handling is done in the main thread, while all of the
rendering

goes
in a secondary one.
Right now, I am creating the window in the main thread, passing it to
the

render thread,
and then the render thread creates the context / does it’s rendering
etc.

I suspect this won’t work on Windows.

I have previously used threads OK with X11. In particular a separate
thread
read SDL
events and sent them to the main thread via some code I wrote. This
worked
fine
on Linux. It did NOT work on Windows ;(

Could be worse. Windows allows some sort of multi-threaded window
handling (at least the last time I read about it). In contrast, OSX
apparently pauses the calling thread, sticks the info into a queue or
something, and executes the graphics call on the main thread the next
time it calls into the OS. The real doozy is iOS: everything has to be
in the main thread.

So yeah, once you leave networking protocols like X11 everything takes
a nose-dive.

=/ That sounds really bad… I wonder how people even do stuff like
multi-threaded
resource loading on OSX then. Looks like a very primitive implementation.

So yeah, once you leave networking protocols like X11 everything takes
a nose-dive.

=/ That sounds really bad… I wonder how people even do stuff like multi-threaded
resource loading on OSX then. Looks like a very primitive implementation.

Actually OSX seems better at this kind of thing these days than Linux.
Apple put a lot of effort into making Mac laptops multi-media capable.

My personal biggest problem with this is that the interfaces are
often Objective C which means a lot of extra learning and messing
about interfacing if you want platform independent code.
It’s not just the multi-media stuff but other essentials like
data structures one needs to understand.

Which is one of the beauties of SDL for me. Big thanks to SDL developers!On 02/08/2013, at 12:22 PM, Jonas Kulla wrote:


john skaller
@john_skaller
http://felix-lang.org

=/ That sounds really bad… I wonder how people even do stuff like

multi-threaded
resource loading on OSX then. Looks like a very primitive implementation.

Here is an article about offloading texture/VBO creation to worker threads:

http://hacksoflife.blogspot.com/2009/08/creating-opengl-textures-or-vbox-on.htmlhttp://hacksoflife.blogspot.com/2009/08/updating-textures-on-fly-with-threads.html
http://hacksoflife.blogspot.com/2009/08/updating-textures-on-fly-with-threads.html

It requires multiple GL contexts and some atomic calls but it can be done,
just remember to use glFlush :)–
Bye,
Gabry