Merge branch 'wip/chergert/fewer-uniforms' into 'master'

ngl: apply fewer uniforms

See merge request GNOME/gtk!3289
This commit is contained in:
Matthias Clasen 2021-03-12 22:55:00 +00:00
commit daed57c30e
3 changed files with 251 additions and 157 deletions

View File

@ -731,98 +731,6 @@ gsk_ngl_command_queue_delete_program (GskNglCommandQueue *self,
glDeleteProgram (program); glDeleteProgram (program);
} }
static inline void
apply_uniform (gconstpointer dataptr,
GskNglUniformInfo info,
guint location)
{
g_assert (dataptr != NULL);
g_assert (info.format > 0);
g_assert (location < GL_MAX_UNIFORM_LOCATIONS);
switch (info.format)
{
case GSK_NGL_UNIFORM_FORMAT_1F:
glUniform1fv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_2F:
glUniform2fv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_3F:
glUniform3fv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_4F:
glUniform4fv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_1FV:
glUniform1fv (location, info.array_count, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_2FV:
glUniform2fv (location, info.array_count, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_3FV:
glUniform3fv (location, info.array_count, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_4FV:
glUniform4fv (location, info.array_count, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_1I:
case GSK_NGL_UNIFORM_FORMAT_TEXTURE:
glUniform1iv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_2I:
glUniform2iv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_3I:
glUniform3iv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_4I:
glUniform4iv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_1UI:
glUniform1uiv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_MATRIX: {
float mat[16];
graphene_matrix_to_float (dataptr, mat);
glUniformMatrix4fv (location, 1, GL_FALSE, mat);
#if 0
/* TODO: If Graphene can give us a peek here on platforms
* where the format is float[16] (most/all x86_64?) then
* We can avoid the SIMD operation to convert the format.
*/
G_STATIC_ASSERT (sizeof (graphene_matrix_t) == 16*4);
glUniformMatrix4fv (location, 1, GL_FALSE, dataptr);
#endif
}
break;
case GSK_NGL_UNIFORM_FORMAT_COLOR:
glUniform4fv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_ROUNDED_RECT:
glUniform4fv (location, 3, dataptr);
break;
default:
g_assert_not_reached ();
}
}
static inline void static inline void
apply_viewport (guint *current_width, apply_viewport (guint *current_width,
guint *current_height, guint *current_height,
@ -1193,8 +1101,7 @@ gsk_ngl_command_queue_execute (GskNglCommandQueue *self,
const GskNglCommandUniform *u = &self->batch_uniforms.items[batch->draw.uniform_offset]; const GskNglCommandUniform *u = &self->batch_uniforms.items[batch->draw.uniform_offset];
for (guint i = 0; i < batch->draw.uniform_count; i++, u++) for (guint i = 0; i < batch->draw.uniform_count; i++, u++)
apply_uniform (gsk_ngl_uniform_state_get_uniform_data (self->uniforms, u->info.offset), gsk_ngl_uniform_state_apply (self->uniforms, program, u->location, u->info);
u->info, u->location);
n_uniforms += batch->draw.uniform_count; n_uniforms += batch->draw.uniform_count;
} }

View File

@ -65,6 +65,8 @@ gsk_ngl_uniform_state_new (void)
state->values_pos = 0; state->values_pos = 0;
state->values_buf = g_malloc (4096); state->values_buf = g_malloc (4096);
memset (state->apply_hash, 0, sizeof state->apply_hash);
return g_steal_pointer (&state); return g_steal_pointer (&state);
} }
@ -221,6 +223,8 @@ gsk_ngl_uniform_state_end_frame (GskNglUniformState *state)
state->values_pos = allocator; state->values_pos = allocator;
g_assert (allocator <= state->values_len); g_assert (allocator <= state->values_len);
memset (state->apply_hash, 0, sizeof state->apply_hash);
} }
gsize gsize

View File

@ -83,6 +83,7 @@ typedef struct _GskNglUniformState
guint8 *values_buf; guint8 *values_buf;
guint values_pos; guint values_pos;
guint values_len; guint values_len;
GskNglUniformInfo apply_hash[512];
} GskNglUniformState; } GskNglUniformState;
/** /**
@ -272,12 +273,15 @@ gsk_ngl_uniform_state_set1f (GskNglUniformState *state,
g_assert (program != 0); g_assert (program != 0);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1F, 1, location, stamp, &info))) if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1F, 1, location, stamp, &info)))
{
if (info->info.initial || u->v0 != value0)
{ {
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1f , 1); GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1f , 1);
u->v0 = value0; u->v0 = value0;
gsk_ngl_uniform_info_changed (info, location, stamp); gsk_ngl_uniform_info_changed (info, location, stamp);
} }
} }
}
static inline void static inline void
gsk_ngl_uniform_state_set2f (GskNglUniformState *state, gsk_ngl_uniform_state_set2f (GskNglUniformState *state,
@ -294,6 +298,8 @@ gsk_ngl_uniform_state_set2f (GskNglUniformState *state,
g_assert (program != NULL); g_assert (program != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2F, 1, location, stamp, &info))) if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2F, 1, location, stamp, &info)))
{
if (info->info.initial || u->v0 != value0 || u->v1 != value1)
{ {
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform2f, 1); GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform2f, 1);
u->v0 = value0; u->v0 = value0;
@ -301,6 +307,7 @@ gsk_ngl_uniform_state_set2f (GskNglUniformState *state,
gsk_ngl_uniform_info_changed (info, location, stamp); gsk_ngl_uniform_info_changed (info, location, stamp);
} }
} }
}
static inline void static inline void
gsk_ngl_uniform_state_set3f (GskNglUniformState *state, gsk_ngl_uniform_state_set3f (GskNglUniformState *state,
@ -318,6 +325,8 @@ gsk_ngl_uniform_state_set3f (GskNglUniformState *state,
g_assert (program != NULL); g_assert (program != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3F, 1, location, stamp, &info))) if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3F, 1, location, stamp, &info)))
{
if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2)
{ {
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform3f, 1); GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform3f, 1);
u->v0 = value0; u->v0 = value0;
@ -326,6 +335,7 @@ gsk_ngl_uniform_state_set3f (GskNglUniformState *state,
gsk_ngl_uniform_info_changed (info, location, stamp); gsk_ngl_uniform_info_changed (info, location, stamp);
} }
} }
}
static inline void static inline void
gsk_ngl_uniform_state_set4f (GskNglUniformState *state, gsk_ngl_uniform_state_set4f (GskNglUniformState *state,
@ -344,6 +354,8 @@ gsk_ngl_uniform_state_set4f (GskNglUniformState *state,
g_assert (program != NULL); g_assert (program != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4F, 1, location, stamp, &info))) if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4F, 1, location, stamp, &info)))
{
if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2 || u->v3 != value3)
{ {
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform4f, 1); GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform4f, 1);
u->v0 = value0; u->v0 = value0;
@ -353,6 +365,7 @@ gsk_ngl_uniform_state_set4f (GskNglUniformState *state,
gsk_ngl_uniform_info_changed (info, location, stamp); gsk_ngl_uniform_info_changed (info, location, stamp);
} }
} }
}
static inline void static inline void
gsk_ngl_uniform_state_set1ui (GskNglUniformState *state, gsk_ngl_uniform_state_set1ui (GskNglUniformState *state,
@ -368,12 +381,15 @@ gsk_ngl_uniform_state_set1ui (GskNglUniformState *state,
g_assert (program != NULL); g_assert (program != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1UI, 1, location, stamp, &info))) if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1UI, 1, location, stamp, &info)))
{
if (info->info.initial || u->v0 != value0)
{ {
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1ui, 1); GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1ui, 1);
u->v0 = value0; u->v0 = value0;
gsk_ngl_uniform_info_changed (info, location, stamp); gsk_ngl_uniform_info_changed (info, location, stamp);
} }
} }
}
static inline void static inline void
gsk_ngl_uniform_state_set1i (GskNglUniformState *state, gsk_ngl_uniform_state_set1i (GskNglUniformState *state,
@ -389,12 +405,15 @@ gsk_ngl_uniform_state_set1i (GskNglUniformState *state,
g_assert (program != NULL); g_assert (program != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1I, 1, location, stamp, &info))) if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1I, 1, location, stamp, &info)))
{
if (info->info.initial || u->v0 != value0)
{ {
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1i, 1); GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1i, 1);
u->v0 = value0; u->v0 = value0;
gsk_ngl_uniform_info_changed (info, location, stamp); gsk_ngl_uniform_info_changed (info, location, stamp);
} }
} }
}
static inline void static inline void
gsk_ngl_uniform_state_set2i (GskNglUniformState *state, gsk_ngl_uniform_state_set2i (GskNglUniformState *state,
@ -411,6 +430,8 @@ gsk_ngl_uniform_state_set2i (GskNglUniformState *state,
g_assert (program != NULL); g_assert (program != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2I, 1, location, stamp, &info))) if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2I, 1, location, stamp, &info)))
{
if (info->info.initial || u->v0 != value0 || u->v1 != value1)
{ {
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform2i, 1); GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform2i, 1);
u->v0 = value0; u->v0 = value0;
@ -418,6 +439,7 @@ gsk_ngl_uniform_state_set2i (GskNglUniformState *state,
gsk_ngl_uniform_info_changed (info, location, stamp); gsk_ngl_uniform_info_changed (info, location, stamp);
} }
} }
}
static inline void static inline void
gsk_ngl_uniform_state_set3i (GskNglUniformState *state, gsk_ngl_uniform_state_set3i (GskNglUniformState *state,
@ -435,6 +457,8 @@ gsk_ngl_uniform_state_set3i (GskNglUniformState *state,
g_assert (program != NULL); g_assert (program != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3I, 1, location, stamp, &info))) if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3I, 1, location, stamp, &info)))
{
if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2)
{ {
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform3i, 1); GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform3i, 1);
u->v0 = value0; u->v0 = value0;
@ -443,6 +467,7 @@ gsk_ngl_uniform_state_set3i (GskNglUniformState *state,
gsk_ngl_uniform_info_changed (info, location, stamp); gsk_ngl_uniform_info_changed (info, location, stamp);
} }
} }
}
static inline void static inline void
gsk_ngl_uniform_state_set4i (GskNglUniformState *state, gsk_ngl_uniform_state_set4i (GskNglUniformState *state,
@ -461,6 +486,8 @@ gsk_ngl_uniform_state_set4i (GskNglUniformState *state,
g_assert (program != NULL); g_assert (program != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4I, 1, location, stamp, &info))) if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4I, 1, location, stamp, &info)))
{
if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2 || u->v3 != value3)
{ {
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform4i, 1); GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform4i, 1);
u->v0 = value0; u->v0 = value0;
@ -470,6 +497,7 @@ gsk_ngl_uniform_state_set4i (GskNglUniformState *state,
gsk_ngl_uniform_info_changed (info, location, stamp); gsk_ngl_uniform_info_changed (info, location, stamp);
} }
} }
}
static inline void static inline void
gsk_ngl_uniform_state_set_rounded_rect (GskNglUniformState *state, gsk_ngl_uniform_state_set_rounded_rect (GskNglUniformState *state,
@ -486,12 +514,15 @@ gsk_ngl_uniform_state_set_rounded_rect (GskNglUniformState *state,
g_assert (rounded_rect != NULL); g_assert (rounded_rect != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_ROUNDED_RECT, 1, location, stamp, &info))) if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_ROUNDED_RECT, 1, location, stamp, &info)))
{
if (info->info.initial || memcmp (u, rounded_rect, sizeof *u) != 0)
{ {
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, GskRoundedRect, 1); GSK_NGL_UNIFORM_STATE_REPLACE (info, u, GskRoundedRect, 1);
memcpy (u, rounded_rect, sizeof *rounded_rect); memcpy (u, rounded_rect, sizeof *rounded_rect);
gsk_ngl_uniform_info_changed (info, location, stamp); gsk_ngl_uniform_info_changed (info, location, stamp);
} }
} }
}
static inline void static inline void
gsk_ngl_uniform_state_set_matrix (GskNglUniformState *state, gsk_ngl_uniform_state_set_matrix (GskNglUniformState *state,
@ -508,12 +539,15 @@ gsk_ngl_uniform_state_set_matrix (GskNglUniformState *state,
g_assert (matrix != NULL); g_assert (matrix != NULL);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_MATRIX, 1, location, stamp, &info))) if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_MATRIX, 1, location, stamp, &info)))
{
if (info->info.initial || memcmp (u, matrix, sizeof *u) != 0)
{ {
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, graphene_matrix_t, 1); GSK_NGL_UNIFORM_STATE_REPLACE (info, u, graphene_matrix_t, 1);
memcpy (u, matrix, sizeof *matrix); memcpy (u, matrix, sizeof *matrix);
gsk_ngl_uniform_info_changed (info, location, stamp); gsk_ngl_uniform_info_changed (info, location, stamp);
} }
} }
}
/** /**
* gsk_ngl_uniform_state_set_texture: * gsk_ngl_uniform_state_set_texture:
@ -545,12 +579,15 @@ gsk_ngl_uniform_state_set_texture (GskNglUniformState *state,
texture_slot -= GL_TEXTURE0; texture_slot -= GL_TEXTURE0;
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_TEXTURE, 1, location, stamp, &info))) if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_TEXTURE, 1, location, stamp, &info)))
{
if (info->info.initial || *u != texture_slot)
{ {
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, guint, 1); GSK_NGL_UNIFORM_STATE_REPLACE (info, u, guint, 1);
*u = texture_slot; *u = texture_slot;
gsk_ngl_uniform_info_changed (info, location, stamp); gsk_ngl_uniform_info_changed (info, location, stamp);
} }
} }
}
/** /**
* gsk_ngl_uniform_state_set_color: * gsk_ngl_uniform_state_set_color:
@ -582,11 +619,14 @@ gsk_ngl_uniform_state_set_color (GskNglUniformState *state,
if (color == NULL) if (color == NULL)
color = &transparent; color = &transparent;
if (info->info.initial || memcmp (color, u, sizeof *u) != 0)
{
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, GdkRGBA, 1); GSK_NGL_UNIFORM_STATE_REPLACE (info, u, GdkRGBA, 1);
memcpy (u, color, sizeof *color); memcpy (u, color, sizeof *color);
gsk_ngl_uniform_info_changed (info, location, stamp); gsk_ngl_uniform_info_changed (info, location, stamp);
} }
} }
}
static inline void static inline void
gsk_ngl_uniform_state_set1fv (GskNglUniformState *state, gsk_ngl_uniform_state_set1fv (GskNglUniformState *state,
@ -604,12 +644,15 @@ gsk_ngl_uniform_state_set1fv (GskNglUniformState *state,
g_assert (count > 0); g_assert (count > 0);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1FV, count, location, stamp, &info))) if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1FV, count, location, stamp, &info)))
{
if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
{ {
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1f, count); GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1f, count);
memcpy (u, value, sizeof (Uniform1f) * count); memcpy (u, value, sizeof (Uniform1f) * count);
gsk_ngl_uniform_info_changed (info, location, stamp); gsk_ngl_uniform_info_changed (info, location, stamp);
} }
} }
}
static inline void static inline void
gsk_ngl_uniform_state_set2fv (GskNglUniformState *state, gsk_ngl_uniform_state_set2fv (GskNglUniformState *state,
@ -627,12 +670,15 @@ gsk_ngl_uniform_state_set2fv (GskNglUniformState *state,
g_assert (count > 0); g_assert (count > 0);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2FV, count, location, stamp, &info))) if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2FV, count, location, stamp, &info)))
{
if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
{ {
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform2f, count); GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform2f, count);
memcpy (u, value, sizeof (Uniform2f) * count); memcpy (u, value, sizeof (Uniform2f) * count);
gsk_ngl_uniform_info_changed (info, location, stamp); gsk_ngl_uniform_info_changed (info, location, stamp);
} }
} }
}
static inline void static inline void
gsk_ngl_uniform_state_set3fv (GskNglUniformState *state, gsk_ngl_uniform_state_set3fv (GskNglUniformState *state,
@ -650,12 +696,15 @@ gsk_ngl_uniform_state_set3fv (GskNglUniformState *state,
g_assert (count > 0); g_assert (count > 0);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3FV, count, location, stamp, &info))) if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3FV, count, location, stamp, &info)))
{
if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
{ {
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform3f, count); GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform3f, count);
memcpy (u, value, sizeof (Uniform3f) * count); memcpy (u, value, sizeof (Uniform3f) * count);
gsk_ngl_uniform_info_changed (info, location, stamp); gsk_ngl_uniform_info_changed (info, location, stamp);
} }
} }
}
static inline void static inline void
gsk_ngl_uniform_state_set4fv (GskNglUniformState *state, gsk_ngl_uniform_state_set4fv (GskNglUniformState *state,
@ -673,12 +722,146 @@ gsk_ngl_uniform_state_set4fv (GskNglUniformState *state,
g_assert (count > 0); g_assert (count > 0);
if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4FV, count, location, stamp, &info))) if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4FV, count, location, stamp, &info)))
{
if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
{ {
GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform4f, count); GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform4f, count);
memcpy (u, value, sizeof (Uniform4f) * count); memcpy (u, value, sizeof (Uniform4f) * count);
gsk_ngl_uniform_info_changed (info, location, stamp); gsk_ngl_uniform_info_changed (info, location, stamp);
} }
} }
}
static inline guint
gsk_ngl_uniform_state_fmix (guint program,
guint location)
{
guint h = (program << 16) | location;
h ^= h >> 16;
h *= 0x85ebca6b;
h ^= h >> 13;
h *= 0xc2b2ae35;
h ^= h >> 16;
return h;
}
/*
* gsk_ngl_uniform_state_apply:
* @state: the uniform state
* @program: the program id
* @location: the location of the uniform
* @offset: the offset of the data within the buffer
* @info: the uniform info
*
* This function can be used to apply state that was previously recorded
* by the #GskNglUniformState.
*
* It is specifically useful from the GskNglCommandQueue to execute uniform
* changes but only when they have changed from the current value.
*/
static inline void
gsk_ngl_uniform_state_apply (GskNglUniformState *state,
guint program,
guint location,
GskNglUniformInfo info)
{
guint index = gsk_ngl_uniform_state_fmix (program, location) % G_N_ELEMENTS (state->apply_hash);
gconstpointer dataptr = GSK_NGL_UNIFORM_VALUE (state->values_buf, info.offset);
/* aligned, can treat as unsigned */
if (*(guint *)&info == *(guint *)&state->apply_hash[index])
return;
state->apply_hash[index] = info;
/* TODO: We could do additional comparisons here to make sure we are
* changing state.
*/
switch (info.format)
{
case GSK_NGL_UNIFORM_FORMAT_1F:
glUniform1fv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_2F:
glUniform2fv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_3F:
glUniform3fv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_4F:
glUniform4fv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_1FV:
glUniform1fv (location, info.array_count, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_2FV:
glUniform2fv (location, info.array_count, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_3FV:
glUniform3fv (location, info.array_count, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_4FV:
glUniform4fv (location, info.array_count, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_1I:
case GSK_NGL_UNIFORM_FORMAT_TEXTURE:
glUniform1iv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_2I:
glUniform2iv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_3I:
glUniform3iv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_4I:
glUniform4iv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_1UI:
glUniform1uiv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_MATRIX: {
float mat[16];
graphene_matrix_to_float (dataptr, mat);
glUniformMatrix4fv (location, 1, GL_FALSE, mat);
#if 0
/* TODO: If Graphene can give us a peek here on platforms
* where the format is float[16] (most/all x86_64?) then
* We can avoid the SIMD operation to convert the format.
*/
G_STATIC_ASSERT (sizeof (graphene_matrix_t) == 16*4);
glUniformMatrix4fv (location, 1, GL_FALSE, dataptr);
#endif
}
break;
case GSK_NGL_UNIFORM_FORMAT_COLOR:
glUniform4fv (location, 1, dataptr);
break;
case GSK_NGL_UNIFORM_FORMAT_ROUNDED_RECT:
glUniform4fv (location, 3, dataptr);
break;
default:
g_assert_not_reached ();
}
}
G_END_DECLS G_END_DECLS