Combine result of two rendering engines on the screen

I have two engines. One for 2D and one for 3D. Both OpenGL and SDL2 based. And I need to draw the
output of the second engine under the output of the second. Do not ask why… (actually you may ask)

I’m afraid I cannot use them one by one at the same GL context, because they both have a bit complex set of states, that conflicting and is very tricky to save/restore between.
So I’m thinking about how to run them in separate threads within separate GL contexs. One (secondary) thread renders its part of scene to some shared object and then another thread (main) renders its part to the screen and puts results of first thread to the screen.

What kind of shared object is better to use? Texture? UBO? just Surface? Will it be portable on different driver implementations?

Or that’s better to do my best in implementing save/restore state mechanism to combine them both in main thread?

Also, could you please share relevant tutorials/examples links, if you have any? Most of googlable links are too basic and the rest is a bit irrelevant or strange.

So why not execute them sequentially with separate contexts but the same window? Unlike over-simplified toolkits (GLUT, GLFW), SDL allows you to create and use multiple contexts with a single window. This is likely to be more straightforward than using multiple threads.

Do you mean SDL_GL_MakeCurrent?

Isn’t context switch too costly to perform it twice a frame?

BTW, there is glfwMakeContextCurrent in GLFW, doesn’t it do the same?

To the extent that this is expensive, that’s a cost you decided to pay when you choose to not keep track of the state the different parts of your application need. There’s no cheap way to change all of the state in the context. So either those different parts of your program know how to set up their state or you have to use mechanisms like context switches to do it for them.

Thanks for the answer!

Yeah, I understand the concept “there are no free goods”. But what’s the price? Is it reasonable?

Just measured it on the simple example with one quad (draw two quads at the same window with 2 different contexts) and got only ~30 microseconds drawback for two switches. But does SDL_GL_MakeCurrent cost scale with the growth of the scene complexity? if so, why?

As I understand, context switch doesn’t copy any resources. It just perform some synchronization between GPU and CPU events. Sounds like it don’t depend on the count of uniforms and so on. Or I misssomething?

Not directly. However:

  1. Swapping contexts on a surface may result in synchronisation. That isn’t necessarily an issue (executing pending commands is work which would have to be performed at some point), but if it means that the GPU goes idle before starting on the commands for the new context, that will have a cost.
  2. Updating the GPU state to reflect the state of the new context may also have a cost.

On the other hand, there may be similar costs with using multiple threads. You only have one GPU, so executing a batch of commands issued on one context then a batch issued on another may require significant changes to GPU state. Much of this will depend upon how the driver manages contexts. If it associates state with framebuffers, switching contexts on a single would be more expensive than switching between framebuffer+context pairs.

All other factors being equal (which they probably aren’t), using two contexts with one framebuffer avoids the need to composite the results. It also avoids the need to render portions of the 3D scene which would be obscured by the 2D overlay (assuming that you render the overlay first), due to early depth test optimisation.

thanks for detailed explanation!