From 2ad4a4754744e71aca472f77e64168dd1a962422 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 10 Sep 2012 08:45:56 +0300 Subject: [PATCH] mesa: glGet: fix parameter lookup for apps using multiple APIs The glGet hash was initialized only once for a single GL API, even if the application later created a context for a different API. This resulted in glGet failing for otherwise valid parameters in a context if that parameter was invalid in another context created earlier. Fix this by using a separate hash table for each API. Signed-off-by: Imre Deak Reviewed-by: Brian Paul Reviewed-by: Oliver McFadden --- src/mesa/main/context.c | 5 ++--- src/mesa/main/get.c | 44 +++++++++++++++++++++++++++-------------- src/mesa/main/mtypes.h | 2 ++ 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index d3fced9460b..29f28bd1887 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -404,9 +404,6 @@ one_time_init( struct gl_context *ctx ) _mesa_get_cpu_features(); - /* context dependence is never a one-time thing... */ - _mesa_init_get_hash(ctx); - for (i = 0; i < 256; i++) { _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F; } @@ -425,6 +422,8 @@ one_time_init( struct gl_context *ctx ) /* per-API one-time init */ if (!(api_init_mask & (1 << ctx->API))) { + _mesa_init_get_hash(ctx); + /* * This is fine as ES does not use the remap table, but it may not be * future-proof. We cannot always initialize the remap table because diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 14208504be5..b46492cf110 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -1385,29 +1385,37 @@ static const struct value_desc values[] = { * collisions for any enum (typical numbers). And the code is very * simple, even though it feels a little magic. */ -static unsigned short table[1024]; +static unsigned short table[API_LAST + 1][1024]; static const int prime_factor = 89, prime_step = 281; #ifdef GET_DEBUG static void -print_table_stats(void) +print_table_stats(int api) { int i, j, collisions[11], count, hash, mask; const struct value_desc *d; - + const char *api_names[] = { + [API_OPENGL] = "GL", + [API_OPENGL_CORE] = "GL_CORE", + [API_OPENGLES] = "GLES", + [API_OPENGLES2] = "GLES2", + }; + const char *api_name; + + api_name = api < Elements(api_names) ? api_names[api] : "N/A"; count = 0; - mask = Elements(table) - 1; + mask = Elements(table[api]) - 1; memset(collisions, 0, sizeof collisions); - for (i = 0; i < Elements(table); i++) { - if (!table[i]) + for (i = 0; i < Elements(table[api]); i++) { + if (!table[api][i]) continue; count++; - d = &values[table[i]]; + d = &values[table[api][i]]; hash = (d->pname * prime_factor); j = 0; while (1) { - if (values[table[hash & mask]].pname == d->pname) + if (values[table[api][hash & mask]].pname == d->pname) break; hash += prime_step; j++; @@ -1419,7 +1427,8 @@ print_table_stats(void) collisions[10]++; } - printf("number of enums: %d (total %d)\n", count, Elements(values)); + printf("number of enums for %s: %d (total %ld)\n", + api_name, count, Elements(values)); for (i = 0; i < Elements(collisions) - 1; i++) if (collisions[i] > 0) printf(" %d enums with %d %scollisions\n", @@ -1438,10 +1447,13 @@ print_table_stats(void) void _mesa_init_get_hash(struct gl_context *ctx) { int i, hash, index, mask; + int api; int api_mask = 0, api_bit; - mask = Elements(table) - 1; - api_bit = 1 << ctx->API; + api = ctx->API; + + mask = Elements(table[api]) - 1; + api_bit = 1 << api; for (i = 0; i < Elements(values); i++) { if (values[i].type == TYPE_API_MASK) { @@ -1454,8 +1466,8 @@ void _mesa_init_get_hash(struct gl_context *ctx) hash = (values[i].pname * prime_factor) & mask; while (1) { index = hash & mask; - if (!table[index]) { - table[index] = i; + if (!table[api][index]) { + table[api][index] = i; break; } hash += prime_step; @@ -1986,11 +1998,13 @@ find_value(const char *func, GLenum pname, void **p, union value *v) struct gl_texture_unit *unit; int mask, hash; const struct value_desc *d; + int api; - mask = Elements(table) - 1; + api = ctx->API; + mask = Elements(table[api]) - 1; hash = (pname * prime_factor); while (1) { - d = &values[table[hash & mask]]; + d = &values[table[api][hash & mask]]; /* If the enum isn't valid, the hash walk ends with index 0, * which is the API mask entry at the beginning of values[]. */ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 40a802f52e6..a827d5c397a 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -3341,6 +3341,8 @@ typedef enum API_OPENGLES, API_OPENGLES2, API_OPENGL_CORE, + + API_LAST = API_OPENGL_CORE, } gl_api; /** -- 2.30.2