Changing states vs Changing context

Hi

As a context is a states holder, it seems that there are two ways to change between sets of states .
Say we have Set A of states , and Set B of states.
In order to exchange between them from time to time, we can do the follows:
Method 1: On the same context, change all set of states.
Method 2: Keep two contexts, one contexts with set A states, second context with set B of states. Just exchange current context.

Does method 2 is practical to use in some conditions?

Thanks
Yossi

A context is more than just states, it’s also objects, and while many objects can be shared between contexts, some objects are not. VAOs are one example of an object type that everybody uses but is not shared.

On some platforms (e.g. Windows) changing the context involves a pipeline flush.

On account of both of these I would suggest that option 2 is completely impractical. State management can be made easier by using container objects where they exist (VAOs again), writing some simple state filtering, never unbinding and setting state before drawing but not resetting after.

Yes. Although given mhagain’s comments about performance on Windows, you probably wouldn’t want to be changing contexts on a per-frame basis with real-time animation.

I’ve used that approach to enforce modularity, in situations where independently-developed code couldn’t safely be relied upon to restore context state. But that was with the fixed-function pipeline, where most of the state was part of the context; nowadays, most of that state would be in uniform variables (which are stored either as part of a program object or in UBOs), or in VAOs, etc.

What for rendering (real time animation) into more than one window, in such case there is need to change contexts each frame, isn’t it?

No, you would generally have one thread running for each window, thus having one context current once for all in each thread.

[QUOTE=Yossi Koren;1288724]Hi

As a context is a states holder, it seems that there are two ways to change between sets of states .
Say we have Set A of states , and Set B of states.
In order to exchange between them from time to time, we can do the follows:
Method 1: On the same context, change all set of states.
Method 2: Keep two contexts, one contexts with set A states, second context with set B of states. Just exchange current context.

Does method 2 is practical to use in some conditions?

Thanks
Yossi[/QUOTE]

If you need to keep context states, then I would keep these states in a structure. Each time you will ‘bind’ or make this structure ‘current’, then you will apply all the states (glEnable, …) with all the values set in all the attributes of your structure.

  1. In a lot of applications all windows are on the same message loop - so it is one thread for all windows.
  2. If you design the application with each window in different thread (and different active context), then every thread calls GPU rendering commands. I heard that it is preferable to call all rendering commands in a sequence and not in parallel.

Any examples on such applications ?
TMO, you are mistaken things. You are mixing different windows with different viewports. Modelers like 3DSMax (where the rendering is split into different point of views) will generally render to a single window. But they split this window into different viewports.

What do you exactly want to do ?

This is true for almost any application which doesn’t explicitly use multi-threading. All of the common GUI toolkits invoke event callbacks in the main thread.

Well, it can be (it seems that effectively Windows MDIs work like this).
But as you’re telling, this is for single-threaded applications. And 3D programs, AFAIK, almost never do that.

Finally, the fact that most toolkits (ie Gtk or Qt) invoke event callbacks in the main thread does not mean that there are effectively distinct windows. For example, in Unix, if you want 2 distinct windows, you’ll generally open 2 distinct displays, then having to call the event checking function twice, one for each display.
It seems that, as stated above, under Windows, you do the opposite: you have a single event loop, then when you receive an event, you check from which window it belongs to.

Both ways will lead to the same approach for multiple OpenGL windows in the same program: you will create two windows, two threads, and within each thread, create a context that you will keep current for all its life.

All common GUI toolkits work like this. If you want to use multiple threads, you have to do this yourself.

None of the common toolkits do this. Certainly, it doesn’t apply to Xt, GTK+, Qt, wxWidgets, GLUT or GLFW.

You could do it yourself, but it will cause problems as the application will appear to the X server as multiple, distinct clients.

Using GUI functions from multiple threads tends to be avoided. Some toolkits specifically disallow this, others officially support it (but don’t have a particularly good track record for getting it right).

Thank you.

Ok, so what about using the same context for all windows as follows, does its performance will be better than replacing contexts?

hglrc = handle for context.

// make context active for window 1
wglMakeCurrent(hdc1, hglrc);
// draw here for window 1

// make context active for window 2
wglMakeCurrent(hdc2, hglrc);
// draw here for window 2
:
:

// make context active for window N
wglMakeCurrent(hdcN, hglrc);
// draw here for window N