Since the specification of state objects seem to be one of the problems of LP, I want to add my 2 cents to this. The whole debate seems to be, what part of the state objets should be mutable/immutable.
Imutable state objects offer fast state switching, because once sucessfully created, the state objects are valid and can be used by the driver without a second thought. But they also imply, that for each distinct state an application needs, it has to keep a prepared state object around, possibly multiple of them specifying the same state (in different parts of the application not knowing of each other).
Mutable state objects offer more flexibility at the application’s side, but force the driver to check the current state at the next “critical” point (like a call to glDrawElements()) over and over again.
The dispute at ARB seems to be, what parts of the state are changed so often that they deserve mutability and what states are usually changed less frequent, so that their immutability would be less a burden to the application developer.
I propose a third way that lies somewhere inbetween. It sounds so easy that it might have been suggested earlier… so please bear with me
To put it easy, I suggest to have fully mutable state objects around and to introduce explicit “critical checkpoints”. Basically, its like telling the driver “I’m done changing the state or this object, please check it and then take it as current state”.
It could work like this:
// create and initialize the state object
GLuint depthstencilstate=0;
glGenTemplates(GL_CLASS_DEPTH_STENCIL_STATE, 1, &depthstencilstate);
glSetPropertyi(depthstencilstate, GL_DEPTH_TEST, GL_TRUE);
glSetPropertyi(depthstencilstate, GL_DEPTH_FUNC, GL_LEQUAL);
GLfloat depthrange[2]={0.0f, 1.0f};
glSetPropertyfv(depthstencilstate, GL_DEPTH_RANGE, depthrange);
// now make it "current", this is the explicit checkpoint for
// the validity of the 'depthstencilstate" object
glSetState(GL_DEPTH_STENCIL_STATE, depthstencilstate)
assert(glGetError()==GL_NO_ERROR); // new state accepted?
Now, this opens many opportunities. As application programmer, I might keep several state-objects around or only manipulate 1 object the whole time. State-objects might undergo even invalid states until glSetState() is actually called.
If glSetState() would keep a ‘Validated’ Flag around, the driver might store, if he already validated the state object or not, thus keeping multiple validated stat objects around might be good for an application performance wise.
glSetState() introduces also opportunities for a driver. Since invalid state objects are not accepted, the ‘Real’ driver state is (almost) never in an invalid state. It reliefs the burden from all drawing commands to check for the current state, if its invalid or not.
Another advantage is, that it would be very easy to create a “delta-state” from the current state (that a particular part of the code is not aware of or even uninterested in) and to implement a very efficient glPushAttrib()/glPopAttrib() replacement. Look at this:
GL uint oldstate=0;
GL uint newstate=0;
glGenTemplates(GL_CLASS_DEPTH_STENCIL_STATE, 1, &oldstate);
glGenTemplates(GL_CLASS_DEPTH_STENCIL_STATE, 1, &newstate);
//retrieve current state and copy it into "oldstate"
glGetState(GL_DEPTH_STENCIL_STATE, oldstate);
//again, retrieve the current state.
// we could also introduce a "glCopyStateObject" function for this
glGetState(GL_DEPTH_STENCIL_STATE, newstate);
// now change only the depth test without touching the rest of it!
glSetPropertyi(newstate, GL_DEPTH_TEST, 0);
// introduce the changed state
glSetState(GL_DEPTH_STENCIL_STATE, newstate);
// draw some stuff
glDrawElements();
...
//now, restore the old state
glSetState(GL_DEPTH_STENCIL_STATE, oldstate);
It might be even possible that the OpenGL context provides “built in state objects” that allow instant access to some properties of them (either for monitoring or controlling something). The ability to specify read-only or write-only properties is also an cool feature. glSetProperty/glGetProperty provide great mechanism for that - they just ignore the call if you used the wrong access mode.
So, ARB guys… where were the problems of the programming models you discussed? I really can’t imagine that those state objects really lead to the fall of LP
[Edit]
I forgot to mention: glSetState() is unlike glBindTexture() or glUseProgram(). It will actually make a copy of the provided state object into the internal state. After glSetState returns, you can freely change the state object again, without hurting the actual context state.