Skip to content

Instantly share code, notes, and snippets.

@Groovounet
Created November 25, 2013 10:57
Show Gist options
  • Save Groovounet/7639664 to your computer and use it in GitHub Desktop.
Save Groovounet/7639664 to your computer and use it in GitHub Desktop.
Ah twitter!
OpenGL is thread-safe which is actually pretty annoying and expective.
OpenGL traditionally uses the "Bind to Edit" model. An alternative is called "Direct State Access" (DSA).
Bind to Edit:
GLuint Texture(0);
glGenTextures(1, &Texture);
glBindTexture(GL_TEXTURE_2D, Texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Direct State Access:
GLuint Texture(0);
glGenTextures(1, &Texture);
glTextureParameteriEXT(Texture, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTextureParameteriEXT(Texture, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
DSA looks nicer but it's slower because OpenGL is thread safe. Each time an OpenGL texture object is accessed an OpenGL implementation need one mutex to access the table that map OpenGL names to OpenGL objects and one mutex to access the object state modified by the API call.
This is because: any thread can create or delete an OpenGL object and any thread can modify an OpenGL object.
But DSA remains a better design because there are three approaches to manage OpenGL states:
1/ States overwrite (We just set all the states necessarilly)
2/ States tracking (We keep a copy of every states)
3/ Assumption (We know how the state should at a logical point of the rendering execution.)
An OpenGL renderer uses a bit of all that but because every OpenGL call is quite expensive we prefer to avoid 1.
DSA is a better approach even if it's more expensive because it's design to provide some garantees to the OpenGL states so that we can use assumption a lot more. We affect the rendering states only when rendering, not when creating objects or do memory transfer. With bind to edit, we need to invalidate some states hence relying on 2 or 1 but in practice more 1 than 2 hence traver the code to reset the OpenGL state because we don't know anymore where we are.
So in my opinion glTextureParameteriEXT(Texture, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); or glTextureWrapS(Texture, GL_CLAMP_TO_EDGE), this is proportionally to the problem, quite decorative.
If I had to got to decorativeness, I'll rather have real enums starting by 0 for GL_TEXTURE_WRAP_S so that behind a simple table access could allow to access the object state and that would give the same performance that glTextureWrapS without an API number explosion.
@grahamsellers
Copy link

You need to strike a balance. There's not a choice between, for example

glTextureParameteriEXT(Texture, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); and glTextureWrapS(Texture, GL_CLAMP_TO_EDGE)

Probably more reasonable would be:

glTextureWrap(GLuint name, GLwrap S, GLwrap T, GLwrap R);

Further, the problem with the mutex is not so much to do with DSA, but with "GLuint name". You need a mutex around the "name -> internal object" conversion, and a mutex around the parameter update. What we really need is:

glTextureWrap(GLhandle texture, GLwrap S, GLwrap T, GLwrap R);

GLhandle is a pointer-sized variable. We redefine the semantics such that a bad "texture" parameter can cause a crash (just like a bad pointer in any other API), rather than a plain error, and that deleting an object from one thread while its in use from another produces undefined behavior (reference counting can alleviate that danger). GLwrap is a strong enumerant. Now we have one API and one mutex to set all three parameters. Further, that mutex is taken only around the target object, not around the namestore that maps names to objects, making it far less likely to be contended.

Similar logic can be applied across the whole API. It's still OpenGL - no need to throw the baby out with the bath water, but it does need a pretty radical overhaul.

@aras-p
Copy link

aras-p commented Nov 25, 2013

Were this facebook, I would have pressed "like" on Graham's comment.

@Groovounet
Copy link
Author

Yeap, indeed handles would be the nicest but I am pragmatic. OpenGL evolves easily but radical changes hit disagreements and there is not enough energy to review anyway.

6 years already that the initial EXT_direct_state_access extension was released and no progress. I would probably support the handle idea but I don't because I don't see any agreement on that and I'll be satisfy with any little progress we can make and ask for more right after.

I am done being an idealist since I read Long Peak specs. :p

@sherief
Copy link

sherief commented Nov 25, 2013

Using opaque pointers as names should have happened a long time ago. RIP Longs Peak.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment