cogl-pipeline: Use a hash table for faster uniform name lookup

The uniform names are now stored in a GPtrArray instead of a linked
list. There is also a hash table to speed up converting names to
locations.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
This commit is contained in:
Neil Roberts 2011-11-04 18:26:17 +00:00
parent 4a7cd0d2ac
commit c269817edd
4 changed files with 25 additions and 18 deletions

View File

@ -258,12 +258,16 @@ struct _CoglContext
[COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_WINSYS_FEATURE_N_FEATURES)]; [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_WINSYS_FEATURE_N_FEATURES)];
void *winsys; void *winsys;
/* List of names of uniforms. These are used like quarks to give a /* Array of names of uniforms. These are used like quarks to give a
unique number to each uniform name except that we ensure that unique number to each uniform name except that we ensure that
they increase sequentially so that we can use the id as an index they increase sequentially so that we can use the id as an index
into a bitfield representing the uniforms that a pipeline into a bitfield representing the uniforms that a pipeline
overrides from its parent */ overrides from its parent. */
GSList *uniform_names; GPtrArray *uniform_names;
/* A hash table to quickly get an index given an existing name. The
name strings are owned by the uniform_names array. The values are
the uniform location cast to a pointer. */
GHashTable *uniform_name_hash;
int n_uniform_names; int n_uniform_names;
/* This defines a list of function pointers that Cogl uses from /* This defines a list of function pointers that Cogl uses from

View File

@ -221,7 +221,9 @@ cogl_context_new (CoglDisplay *display,
g_assert_not_reached (); g_assert_not_reached ();
} }
context->uniform_names = NULL; context->uniform_names =
g_ptr_array_new_with_free_func ((GDestroyNotify) g_free);
context->uniform_name_hash = g_hash_table_new (g_str_hash, g_str_equal);
context->n_uniform_names = 0; context->n_uniform_names = 0;
/* Initialise the driver specific state */ /* Initialise the driver specific state */
@ -484,8 +486,8 @@ _cogl_context_free (CoglContext *context)
_cogl_destroy_texture_units (); _cogl_destroy_texture_units ();
g_slist_foreach (context->uniform_names, (GFunc) g_free, NULL); g_ptr_array_free (context->uniform_names, TRUE);
g_slist_free (context->uniform_names); g_hash_table_destroy (context->uniform_name_hash);
g_byte_array_free (context->buffer_map_fallback_array, TRUE); g_byte_array_free (context->buffer_map_fallback_array, TRUE);

View File

@ -598,7 +598,7 @@ flush_uniform_cb (int uniform_num, void *user_data)
if (uniform_location == UNIFORM_LOCATION_UNKNOWN) if (uniform_location == UNIFORM_LOCATION_UNKNOWN)
{ {
const char *uniform_name = const char *uniform_name =
g_slist_nth (data->ctx->uniform_names, uniform_num)->data; g_ptr_array_index (data->ctx->uniform_names, uniform_num);
uniform_location = uniform_location =
data->ctx->glGetUniformLocation (data->program_state->program, data->ctx->glGetUniformLocation (data->program_state->program,

View File

@ -2871,8 +2871,8 @@ int
cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, cogl_pipeline_get_uniform_location (CoglPipeline *pipeline,
const char *uniform_name) const char *uniform_name)
{ {
GSList *l; void *location_ptr;
int location = 0; char *uniform_name_copy;
_COGL_GET_CONTEXT (ctx, -1); _COGL_GET_CONTEXT (ctx, -1);
@ -2884,16 +2884,17 @@ cogl_pipeline_get_uniform_location (CoglPipeline *pipeline,
be. */ be. */
/* Look for an existing uniform with this name */ /* Look for an existing uniform with this name */
for (l = ctx->uniform_names; l; l = l->next) if (g_hash_table_lookup_extended (ctx->uniform_name_hash,
{ uniform_name,
if (!strcmp (uniform_name, l->data)) NULL,
return location; &location_ptr))
return GPOINTER_TO_INT (location_ptr);
location++; uniform_name_copy = g_strdup (uniform_name);
} g_ptr_array_add (ctx->uniform_names, uniform_name_copy);
g_hash_table_insert (ctx->uniform_name_hash,
ctx->uniform_names = uniform_name_copy,
g_slist_append (ctx->uniform_names, g_strdup (uniform_name)); GINT_TO_POINTER (ctx->n_uniform_names));
return ctx->n_uniform_names++; return ctx->n_uniform_names++;
} }