You can utilize ARB_sync or in other words sync objects which have been core since 3.2.
From the point-of-view of OpenGL then right after issuing a specific command (you want to know whether has finished), you'd insert a fence.
Say you want to check if a
glDrawArrays() call has been executed.
GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
Note that if
glFenceSync() fails it will return
You can now check whether it has finished by doing:
GLint signaled = 0;
glGetSynciv(sync, GL_SYNC_STATUS, 1, NULL, &signaled);
if (signaled == GL_SIGNALED)
// Not done
You can then of course repeatably call
glGetSynciv() and check when you receive
If you want to completely block until it's done then you can do:
GLenum status = glClientWaitSync(sync, 0, 0);
if (status == GL_CONDITION_SATISFIED)
It blocks and waits for up to
timeout nanoseconds (the last parameter).
Remember to delete the sync object again:
When it comes to WebGL. Then note that sync objects are not supported in WebGL 1.0. They are however in WebGL 2.0 in the form of WebGLSync.
The equivalent to the above code in WebGL 2.0 would be the following:
var sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
var signaled = gl.getSyncParameter(sync, gl.SYNC_STATUS);
if (signaled == gl.SIGNALED)
// Not done
var status = gl.clientWaitSync(sync, 0, 0);
if (status == gl.CONDITION_SATISFIED)