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)];
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
they increase sequentially so that we can use the id as an index
into a bitfield representing the uniforms that a pipeline
overrides from its parent */
GSList *uniform_names;
overrides from its parent. */
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;
/* 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 ();
}
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;
/* Initialise the driver specific state */
@ -484,8 +486,8 @@ _cogl_context_free (CoglContext *context)
_cogl_destroy_texture_units ();
g_slist_foreach (context->uniform_names, (GFunc) g_free, NULL);
g_slist_free (context->uniform_names);
g_ptr_array_free (context->uniform_names, TRUE);
g_hash_table_destroy (context->uniform_name_hash);
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)
{
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 =
data->ctx->glGetUniformLocation (data->program_state->program,

View File

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