summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorImre Deak <[email protected]>2012-09-10 08:45:56 +0300
committerOliver McFadden <[email protected]>2012-10-10 12:43:05 +0300
commit2ad4a4754744e71aca472f77e64168dd1a962422 (patch)
treef49d9c3ed47bcc8c87cb68d52fe25861ac3d2a4b
parent7182a1fc5ea49dffb7678f6248d5c13a003aca62 (diff)
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 <[email protected]> Reviewed-by: Brian Paul <[email protected]> Reviewed-by: Oliver McFadden <[email protected]>
-rw-r--r--src/mesa/main/context.c5
-rw-r--r--src/mesa/main/get.c44
-rw-r--r--src/mesa/main/mtypes.h2
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;
/**