[Mesa-dev] [PATCH v3 2/8] mesa: glGet: fix parameter lookup for apps using multiple APIs

Oliver McFadden oliver.mcfadden at linux.intel.com
Mon Oct 1 04:08:20 PDT 2012


On Mon, Oct 01, 2012 at 01:37:59PM +0300, Imre Deak wrote:
> 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 <imre.deak at intel.com>
> Reviewed-by: Brian Paul <brianp at vmware.com>
Reviewed-by: Oliver McFadden <oliver.mcfadden at linux.intel.com>
> ---
>  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 c50504d..bc1f42d 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 1420850..b46492c 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 ba43e57..f185ffd 100644
> --- a/src/mesa/main/mtypes.h
> +++ b/src/mesa/main/mtypes.h
> @@ -3340,6 +3340,8 @@ typedef enum
>     API_OPENGLES,
>     API_OPENGLES2,
>     API_OPENGL_CORE,
> +
> +   API_LAST = API_OPENGL_CORE,
>  } gl_api;
>  
>  /**
> -- 
> 1.7.9.5
> 

-- 
Oliver McFadden.


More information about the mesa-dev mailing list