mesa: convert macros to inline functions
[mesa.git] / src / mesa / main / extensions.c
index 750b12f73cc2760d7d50c18b919811c310cd9fce..7504b8a85db6589724e729a6cec81f8aac684d4b 100644 (file)
@@ -73,12 +73,14 @@ struct extension {
  */
 static const struct extension extension_table[] = {
    /* ARB Extensions */
+   { "GL_ARB_ES2_compatibility",                   o(ARB_ES2_compatibility),                   GL             },
    { "GL_ARB_blend_func_extended",                 o(ARB_blend_func_extended),                 GL             },
    { "GL_ARB_copy_buffer",                         o(ARB_copy_buffer),                         GL             },
    { "GL_ARB_depth_buffer_float",                  o(ARB_depth_buffer_float),                  GL             },
    { "GL_ARB_depth_clamp",                         o(ARB_depth_clamp),                         GL             },
    { "GL_ARB_depth_texture",                       o(ARB_depth_texture),                       GL             },
    { "GL_ARB_draw_buffers",                        o(ARB_draw_buffers),                        GL             },
+   { "GL_ARB_draw_buffers_blend",                  o(ARB_draw_buffers_blend),                  GL             },
    { "GL_ARB_draw_elements_base_vertex",           o(ARB_draw_elements_base_vertex),           GL             },
    { "GL_ARB_draw_instanced",                      o(ARB_draw_instanced),                      GL             },
    { "GL_ARB_explicit_attrib_location",            o(ARB_explicit_attrib_location),            GL             },
@@ -87,6 +89,7 @@ static const struct extension extension_table[] = {
    { "GL_ARB_fragment_program_shadow",             o(ARB_fragment_program_shadow),             GL             },
    { "GL_ARB_fragment_shader",                     o(ARB_fragment_shader),                     GL             },
    { "GL_ARB_framebuffer_object",                  o(ARB_framebuffer_object),                  GL             },
+   { "GL_ARB_framebuffer_sRGB",                    o(EXT_framebuffer_sRGB),                    GL             },
    { "GL_ARB_half_float_pixel",                    o(ARB_half_float_pixel),                    GL             },
    { "GL_ARB_half_float_vertex",                   o(ARB_half_float_vertex),                   GL             },
    { "GL_ARB_instanced_arrays",                    o(ARB_instanced_arrays),                    GL             },
@@ -195,6 +198,7 @@ static const struct extension extension_table[] = {
    { "GL_EXT_texture_rectangle",                   o(NV_texture_rectangle),                    GL             },
    { "GL_EXT_texture_shared_exponent",             o(EXT_texture_shared_exponent),             GL             },
    { "GL_EXT_texture_sRGB",                        o(EXT_texture_sRGB),                        GL             },
+   { "GL_EXT_texture_sRGB_decode",                 o(EXT_texture_sRGB_decode),                        GL             },
    { "GL_EXT_texture_swizzle",                     o(EXT_texture_swizzle),                     GL             },
    { "GL_EXT_texture_type_2_10_10_10_REV",         o(dummy_true),                                         ES2 },
    { "GL_EXT_timer_query",                         o(EXT_timer_query),                         GL             },
@@ -232,7 +236,7 @@ static const struct extension extension_table[] = {
    { "GL_OES_read_format",                         o(OES_read_format),                         GL | ES1       },
    { "GL_OES_rgb8_rgba8",                          o(EXT_framebuffer_object),                       ES1 | ES2 },
    { "GL_OES_single_precision",                    o(dummy_true),                                   ES1       },
-   { "GL_OES_standard_derivatives",                o(ARB_fragment_shader),                                ES2 },
+   { "GL_OES_standard_derivatives",                o(OES_standard_derivatives),                           ES2 },
    { "GL_OES_stencil1",                            o(dummy_false),                     DISABLE                },
    { "GL_OES_stencil4",                            o(dummy_false),                     DISABLE                },
    { "GL_OES_stencil8",                            o(EXT_framebuffer_object),                       ES1 | ES2 },
@@ -246,6 +250,7 @@ static const struct extension extension_table[] = {
 
    /* Vendor extensions */
    { "GL_3DFX_texture_compression_FXT1",           o(TDFX_texture_compression_FXT1),           GL             },
+   { "GL_AMD_conservative_depth",                  o(AMD_conservative_depth),                  GL             },
    { "GL_APPLE_client_storage",                    o(APPLE_client_storage),                    GL             },
    { "GL_APPLE_object_purgeable",                  o(APPLE_object_purgeable),                  GL             },
    { "GL_APPLE_packed_pixels",                     o(APPLE_packed_pixels),                     GL             },
@@ -304,10 +309,12 @@ static const struct extension extension_table[] = {
 static size_t
 name_to_offset(const char* name)
 {
+   const struct extension *i;
+
    if (name == 0)
       return 0;
 
-   for (const struct extension *i = extension_table; i->name != 0; ++i) {
+   for (i = extension_table; i->name != 0; ++i) {
       if (strcmp(name, i->name) == 0)
         return i->offset;
    }
@@ -349,6 +356,7 @@ static const size_t default_extensions[] = {
    o(EXT_vertex_array),
 
    o(OES_read_format),
+   o(OES_standard_derivatives),
 
    /* Vendor Extensions */
    o(APPLE_packed_pixels),
@@ -376,6 +384,7 @@ _mesa_enable_sw_extensions(struct gl_context *ctx)
    ctx->Extensions.ARB_depth_texture = GL_TRUE;
    /*ctx->Extensions.ARB_draw_buffers = GL_TRUE;*/
    ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE;
+   ctx->Extensions.ARB_draw_instanced = GL_TRUE;
    ctx->Extensions.ARB_explicit_attrib_location = GL_TRUE;
    ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
 #if FEATURE_ARB_fragment_program
@@ -482,6 +491,7 @@ _mesa_enable_sw_extensions(struct gl_context *ctx)
    ctx->Extensions.EXT_texture_lod_bias = GL_TRUE;
 #if FEATURE_EXT_texture_sRGB
    ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
+   ctx->Extensions.EXT_texture_sRGB_decode = GL_TRUE;
 #endif
    ctx->Extensions.EXT_texture_swizzle = GL_TRUE;
 #if FEATURE_EXT_transform_feedback
@@ -651,13 +661,15 @@ _mesa_enable_2_1_extensions(struct gl_context *ctx)
 static GLboolean
 set_extension( struct gl_context *ctx, const char *name, GLboolean state )
 {
+   size_t offset;
+
    if (ctx->Extensions.String) {
       /* The string was already queried - can't change it now! */
       _mesa_problem(ctx, "Trying to enable/disable extension after glGetString(GL_EXTENSIONS): %s", name);
       return GL_FALSE;
    }
 
-   size_t offset = name_to_offset(name);
+   offset = name_to_offset(name);
    if (offset == 0) {
       _mesa_problem(ctx, "Trying to enable/disable unknown extension %s",
                    name);
@@ -704,90 +716,82 @@ _mesa_disable_extension( struct gl_context *ctx, const char *name )
 GLboolean
 _mesa_extension_is_enabled( struct gl_context *ctx, const char *name )
 {
+   size_t offset;
+   GLboolean *base;
+
    if (name == 0)
       return GL_FALSE;
 
-   size_t offset = name_to_offset(name);
+   offset = name_to_offset(name);
    if (offset == 0)
       return GL_FALSE;
-   GLboolean *base = (GLboolean *) &ctx->Extensions;
+   base = (GLboolean *) &ctx->Extensions;
    return base[offset];
 }
 
 
 /**
- * Append string 'b' onto string 'a'.  Free 'a' and return new string.
- */
-static char *
-append(const char *a, const char *b)
-{
-   const GLuint aLen = a ? strlen(a) : 0;
-   const GLuint bLen = b ? strlen(b) : 0;
-   char *s = calloc(1, aLen + bLen + 1);
-   if (s) {
-      if (a)
-         memcpy(s, a, aLen);
-      if (b)
-         memcpy(s + aLen, b, bLen);
-      s[aLen + bLen] = '\0';
-   }
-   if (a)
-      free((void *) a);
-   return s;
-}
-
-
-/**
- * Check the MESA_EXTENSION_OVERRIDE env var.
- * For extension names that are recognized, turn them on.  For extension
- * names that are recognized and prefixed with '-', turn them off.
- * Return a string of the unknown/leftover names.
+ * \brief Apply the \c MESA_EXTENSION_OVERRIDE environment variable.
  *
- * Returnd string needs to be freed.
+ * \c MESA_EXTENSION_OVERRIDE is a space-separated list of extensions to
+ * enable or disable. The list is processed thus:
+ *    - Enable recognized extension names that are prefixed with '+'.
+ *    - Disable recognized extension names that are prefixed with '-'.
+ *    - Enable recognized extension names that are not prefixed.
+ *    - Collect unrecognized extension names in a new string.
+ *
+ * \return Space-separated list of unrecognized extension names (which must
+ *    be freed). Does not return \c NULL.
  */
 static char *
 get_extension_override( struct gl_context *ctx )
 {
-   const char *envExt = _mesa_getenv("MESA_EXTENSION_OVERRIDE");
-   char *extraExt = NULL;
-   char ext[1000];
-   GLuint extLen = 0;
-   GLuint i;
-   GLboolean disableExt = GL_FALSE;
-
-   if (!envExt)
-      return NULL;
+   const char *env_const= _mesa_getenv("MESA_EXTENSION_OVERRIDE");
+   char *env;
+   char *ext;
+   char *extra_exts;
+   int len;
+
+   if (env_const == NULL) {
+      /* Return the empty string rather than NULL. This simplifies the logic
+       * of client functions. */
+      return calloc(1, sizeof(char));
+   }
 
-   for (i = 0; ; i++) {
-      if (envExt[i] == '\0' || envExt[i] == ' ') {
-         /* terminate/process 'ext' if extLen > 0 */
-         if (extLen > 0) {
-            assert(extLen < sizeof(ext));
-            /* enable extension named by 'ext' */
-            ext[extLen] = 0;
-            if (!set_extension(ctx, ext, !disableExt)) {
-               /* unknown extension name, append it to extraExt */
-               if (extraExt) {
-                  extraExt = append(extraExt, " ");
-               }
-               extraExt = append(extraExt, ext);
-            }
-            extLen = 0;
-            disableExt = GL_FALSE;
-         }
-         if (envExt[i] == '\0')
-            break;
+   /* extra_exts: List of unrecognized extensions. */
+   extra_exts = calloc(strlen(env_const), sizeof(char));
+
+   /* Copy env_const because strtok() is destructive. */
+   env = strdup(env_const);
+   for (ext = strtok(env, " "); ext != NULL; ext = strtok(NULL, " ")) {
+      int enable;
+      int recognized;
+      switch (ext[0]) {
+      case '+':
+         enable = 1;
+         ++ext;
+         break;
+      case '-':
+         enable = 0;
+         ++ext;
+         break;
+      default:
+         enable = 1;
+         break;
       }
-      else if (envExt[i] == '-') {
-         disableExt = GL_TRUE;
-      }
-      else {
-         /* accumulate this non-space character */
-         ext[extLen++] = envExt[i];
+      recognized = set_extension(ctx, ext, enable);
+      if (!recognized) {
+         strcat(extra_exts, ext);
+         strcat(extra_exts, " ");
       }
    }
 
-   return extraExt;
+   /* Remove trailing space. */
+   len  = strlen(extra_exts);
+   if (extra_exts[len - 1] == ' ')
+      extra_exts[len - 1] = '\0';
+
+   return extra_exts;
 }
 
 
@@ -802,15 +806,17 @@ _mesa_init_extensions( struct gl_context *ctx )
 {
    GLboolean *base = (GLboolean *) &ctx->Extensions;
    GLboolean *sentinel = base + o(extension_sentinel);
+   GLboolean *i;
+   const size_t *j;
 
    /* First, turn all extensions off. */
-   for (GLboolean *i = base; i != sentinel; ++i)
+   for (i = base; i != sentinel; ++i)
       *i = GL_FALSE;
 
    /* Then, selectively turn default extensions on. */
    ctx->Extensions.dummy_true = GL_TRUE;
-   for (const size_t *i = default_extensions; *i != 0; ++i)
-      base[*i] = GL_TRUE;
+   for (j = default_extensions; *j != 0; ++j)
+      base[*j] = GL_TRUE;
 }
 
 
@@ -828,9 +834,10 @@ _mesa_make_extension_string(struct gl_context *ctx)
    /* String of extra extensions. */
    char *extra_extensions = get_extension_override(ctx);
    GLboolean *base = (GLboolean *) &ctx->Extensions;
+   const struct extension *i;
 
    /* Compute length of the extension string. */
-   for (const struct extension *i = extension_table; i->name != 0; ++i) {
+   for (i = extension_table; i->name != 0; ++i) {
       if (base[i->offset] && (i->api_set & (1 << ctx->API))) {
         length += strlen(i->name) + 1; /* +1 for space */
       }
@@ -845,7 +852,7 @@ _mesa_make_extension_string(struct gl_context *ctx)
    }
 
    /* Build the extension string.*/
-   for (const struct extension *i = extension_table; i->name != 0; ++i) {
+   for (i = extension_table; i->name != 0; ++i) {
       if (base[i->offset] && (i->api_set & (1 << ctx->API))) {
          strcat(exts, i->name);
          strcat(exts, " ");
@@ -865,12 +872,15 @@ _mesa_make_extension_string(struct gl_context *ctx)
 GLuint
 _mesa_get_extension_count(struct gl_context *ctx)
 {
+   GLboolean *base;
+   const struct extension *i;
+
    /* only count once */
    if (ctx->Extensions.Count != 0)
       return ctx->Extensions.Count;
 
-   GLboolean *base = (GLboolean *) &ctx->Extensions;
-   for (const struct extension *i = extension_table; i->name != 0; ++i) {
+   base = (GLboolean *) &ctx->Extensions;
+   for (i = extension_table; i->name != 0; ++i) {
       if (base[i->offset]) {
         ctx->Extensions.Count++;
       }
@@ -884,12 +894,16 @@ _mesa_get_extension_count(struct gl_context *ctx)
 const GLubyte *
 _mesa_get_enabled_extension(struct gl_context *ctx, GLuint index)
 {
+   const GLboolean *base;
+   size_t n;
+   const struct extension *i;
+
    if (index < 0)
       return NULL;
 
-   const GLboolean *base = (GLboolean*) &ctx->Extensions;
-   size_t n = 0;
-   for (const struct extension *i = extension_table; i->name != 0; ++i) {
+   base = (GLboolean*) &ctx->Extensions;
+   n = 0;
+   for (i = extension_table; i->name != 0; ++i) {
       if (n == index && base[i->offset]) {
         return (GLubyte*) i->name;
       } else if (base[i->offset]) {