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:
parent
4a7cd0d2ac
commit
c269817edd
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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++;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user