gl: Track the current uniform state for custom programs

This allows us to avoid updating uniforms if that is not necessary. This
in turn allows us to sometimes reuse the same draw op by just extending the
vertex array size we draw rather than doing a separate glDraw call.

For example, in the fishbowl demo, all the icons added at the same
time will have the same time and size, so we emit single draw calls
with 100s of triangles instead of 100s of draw calls with 2 triangles.
This commit is contained in:
Alexander Larsson 2020-09-29 11:52:39 +02:00
parent 2e5caa68bc
commit 51ab56d33a
2 changed files with 27 additions and 0 deletions

View File

@ -640,7 +640,28 @@ ops_set_gl_shader_args (RenderOpBuilder *builder,
float height,
const guchar *uniform_data)
{
ProgramState *current_program_state = get_current_program_state (builder);
OpGLShader *op;
gsize args_size = gsk_gl_shader_get_args_size (shader);
if (current_program_state)
{
if (current_program_state->gl_shader.width == width &&
current_program_state->gl_shader.height == height &&
current_program_state->gl_shader.uniform_data_len == args_size &&
memcmp (current_program_state->gl_shader.uniform_data, uniform_data, args_size) == 0)
return;
current_program_state->gl_shader.width = width;
current_program_state->gl_shader.height = height;
if (args_size > sizeof (current_program_state->gl_shader.uniform_data))
current_program_state->gl_shader.uniform_data_len = 0;
else
{
current_program_state->gl_shader.uniform_data_len = args_size;
memcpy (current_program_state->gl_shader.uniform_data, uniform_data, args_size);
}
}
op = ops_begin (builder, OP_CHANGE_GL_SHADER_ARGS);
op->shader = shader;

View File

@ -79,6 +79,12 @@ typedef struct
float end;
float radius[2]; /* h/v */
} radial_gradient;
struct {
float width;
float height;
gint uniform_data_len;
guchar uniform_data[32];
} gl_shader;
};
} ProgramState;