Question

I am running renderer in a separate thread at 60FPS (16ms).

Following code produces random stuttering ...

long testTime = System.nanoTime();
GL20.glUniformMatrix4(
    GL20.glGetUniformLocation(getProgram(), "projectionMatrix"),
    false,
    matrix4fBuffer // holds projection matrix
);
testTime = System.nanoTime() - testTime;
if (testTime > 1000000) {
    System.out.println("DELAY " + (testTime / 1000000) ); // 22-30ms
}

GL20.glUniformMatrix4 call randomly takes around 22-30ms (every 10s, 30s, 45s, ...) which causes random slowdown (stuttering). Normally it takes 0ms (couple of nanoseconds).

I am testing with only one object being rendered (using programmable pipeline - shaders, OpenGL >= 3.3).

Other pieces of this example:

getProgram() // simply returns integer

// This is called before GL20.GLUniformMatrix4
FloatBuffer matrix4fBuffer = BufferUtils.createFloatBuffer(16);
projectionMatrix.store(matrix4fBuffer);
matrix4fBuffer.flip();

Any idea what is happening here?

EDIT: I forgot to mention that I am running render and update in separate threads. I guess it could be related with thread scheduling?

EDIT: Okay I also tested this in single threaded environment and the problem persists ... I have also found out that other calls to glUnuformMatrix4 do not cause problems e.g.:

long testTime = System.nanoTime();
state.model.store(buffer);
buffer.flip();
GL20.glUniformMatrix4(
    GL20.glGetUniformLocation(shader.getProgram(), "modelMatrix"),
    false,
    buffer
);
testTime = System.nanoTime() - testTime;
if (testTime > 16000000) {
    System.out.println("DELAY MODEL" + (testTime / 1000000) );
}
Was it helpful?

Solution

Stop doing this:

GL20.glUniformMatrix4(
    GL20.glGetUniformLocation(getProgram(), "projectionMatrix"),
    [...]

Uniform locations do not change after you link your program, and querying anything from OpenGL is a great way to kill performance.

This particular Get function is particularly expensive because it uses a string to identify the location you are searching for. String comparisons are slow unless optimized into something like a trie, hash tables, etc... and the expense grows as you add more potential matches to the set of searched strings. Neither OpenGL nor GLSL defines how this function has to be implemented, but you should assume that your implementation is as stupid as they come if you are concerned about performance.

Keep a GLint handy for your frequently used named uniforms. I would honestly suggest writing a class that encapsulates a GLSL program object, and then subclass this for any specialization. The specialized classes would store all of the uniform locations they need and you would never have to query GL for uniform locations.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top