diff --git a/cogl/cogl-config-private.h b/cogl/cogl-config-private.h index 14b43bb66..c946d54a2 100644 --- a/cogl/cogl-config-private.h +++ b/cogl/cogl-config-private.h @@ -33,5 +33,7 @@ _cogl_config_read (void); extern char *_cogl_config_driver; extern char *_cogl_config_renderer; +extern char *_cogl_config_disable_gl_extensions; +extern char *_cogl_config_override_gl_version; #endif /* __COGL_CONFIG_PRIVATE_H */ diff --git a/cogl/cogl-config.c b/cogl/cogl-config.c index 81cfaa6f6..a000dd9d5 100644 --- a/cogl/cogl-config.c +++ b/cogl/cogl-config.c @@ -35,11 +35,27 @@ char *_cogl_config_driver; char *_cogl_config_renderer; +char *_cogl_config_disable_gl_extensions; +char *_cogl_config_override_gl_version; + +/* Array of config options that just set a global string */ +static const struct +{ + const char *conf_name; + char **variable; +} cogl_config_string_options[] = + { + { "COGL_DRIVER", &_cogl_config_driver }, + { "COGL_RENDERER", &_cogl_config_renderer }, + { "COGL_DISABLE_GL_EXTENSIONS", &_cogl_config_disable_gl_extensions }, + { "COGL_OVERRIDE_GL_VERSION", &_cogl_config_override_gl_version } + }; static void _cogl_config_process (GKeyFile *key_file) { char *value; + int i; value = g_key_file_get_string (key_file, "global", "COGL_DEBUG", NULL); if (value) @@ -59,22 +75,17 @@ _cogl_config_process (GKeyFile *key_file) g_free (value); } - value = g_key_file_get_string (key_file, "global", "COGL_DRIVER", NULL); - if (value) + for (i = 0; i < G_N_ELEMENTS (cogl_config_string_options); i++) { - if (_cogl_config_driver) - g_free (_cogl_config_driver); + const char *conf_name = cogl_config_string_options[i].conf_name; + char **variable = cogl_config_string_options[i].variable; - _cogl_config_driver = value; - } - - value = g_key_file_get_string (key_file, "global", "COGL_RENDERER", NULL); - if (value) - { - if (_cogl_config_renderer) - g_free (_cogl_config_renderer); - - _cogl_config_renderer = value; + value = g_key_file_get_string (key_file, "global", conf_name, NULL); + if (value) + { + g_free (*variable); + *variable = value; + } } } diff --git a/cogl/cogl-context-private.h b/cogl/cogl-context-private.h index 1e96ad1b2..85d107c67 100644 --- a/cogl/cogl-context-private.h +++ b/cogl/cogl-context-private.h @@ -353,4 +353,10 @@ void _cogl_context_set_current_modelview_entry (CoglContext *context, CoglMatrixEntry *entry); +const char * +_cogl_context_get_gl_extensions (CoglContext *context); + +const char * +_cogl_context_get_gl_version (CoglContext *context); + #endif /* __COGL_CONTEXT_PRIVATE_H */ diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c index 3c39855fa..693cd5021 100644 --- a/cogl/cogl-context.c +++ b/cogl/cogl-context.c @@ -48,6 +48,7 @@ #include "cogl-attribute-private.h" #include "cogl1-context.h" #include "cogl-gpu-info-private.h" +#include "cogl-config-private.h" #include @@ -617,3 +618,107 @@ _cogl_context_set_current_modelview_entry (CoglContext *context, _cogl_matrix_entry_unref (context->current_modelview_entry); context->current_modelview_entry = entry; } + +const char * +_cogl_context_get_gl_extensions (CoglContext *context) +{ + const char *env_disabled_extensions; + + if ((env_disabled_extensions = g_getenv ("COGL_DISABLE_GL_EXTENSIONS")) + || _cogl_config_disable_gl_extensions) + { + static CoglUserDataKey extensions_key; + const char *enabled_extensions; + char **split_enabled_extensions; + char **split_env_disabled_extensions; + char **split_conf_disabled_extensions; + char **e; + GString *result; + + /* We need to return a const string so we'll attach the results + * to the CoglContext to avoid leaking the generated string. + * This string is only used rarely so we are using + * cogl_object_set_user_data instead of adding an explicit + * member to CoglContext to avoid making the struct bigger */ + + enabled_extensions = + cogl_object_get_user_data (COGL_OBJECT (context), &extensions_key); + if (enabled_extensions) + return enabled_extensions; + + enabled_extensions = (const char *) context->glGetString (GL_EXTENSIONS); + + split_enabled_extensions = g_strsplit (enabled_extensions, + " ", + 0 /* no max tokens */); + + if (env_disabled_extensions) + split_env_disabled_extensions = + g_strsplit (env_disabled_extensions, + ",", + 0 /* no max tokens */); + else + split_env_disabled_extensions = NULL; + + if (_cogl_config_disable_gl_extensions) + split_conf_disabled_extensions = + g_strsplit (_cogl_config_disable_gl_extensions, + ",", + 0 /* no max tokens */); + else + split_conf_disabled_extensions = NULL; + + result = g_string_new (NULL); + + for (e = split_enabled_extensions; *e; e++) + { + char **d; + + if (split_env_disabled_extensions) + for (d = split_env_disabled_extensions; *d; d++) + if (!strcmp (*e, *d)) + goto disabled; + if (split_conf_disabled_extensions) + for (d = split_conf_disabled_extensions; *d; d++) + if (!strcmp (*e, *d)) + goto disabled; + + if (result->len > 0) + g_string_append_c (result, ' '); + g_string_append (result, *e); + + disabled: + continue; + } + + enabled_extensions = g_string_free (result, FALSE); + + g_strfreev (split_enabled_extensions); + if (split_env_disabled_extensions) + g_strfreev (split_env_disabled_extensions); + if (split_conf_disabled_extensions) + g_strfreev (split_conf_disabled_extensions); + + cogl_object_set_user_data (COGL_OBJECT (context), + &extensions_key, + (void *) enabled_extensions, + (CoglUserDataDestroyCallback) g_free); + + return enabled_extensions; + } + else + return (const char *) context->glGetString (GL_EXTENSIONS); +} + +const char * +_cogl_context_get_gl_version (CoglContext *context) +{ + const char *version_override; + + if ((version_override = g_getenv ("COGL_OVERRIDE_GL_VERSION"))) + return version_override; + else if (_cogl_config_override_gl_version) + return _cogl_config_override_gl_version; + else + return (const char *) context->glGetString (GL_VERSION); +} diff --git a/cogl/cogl-debug.c b/cogl/cogl-debug.c index 63856d4fd..4498d418c 100644 --- a/cogl/cogl-debug.c +++ b/cogl/cogl-debug.c @@ -182,6 +182,16 @@ _cogl_parse_debug_string (const char *value, OPT (IGNORED, "ignored", "verbose", "ignored", \ N_("Enables all non-behavioural debug options")); #undef OPT + + g_printerr ("\n" + "%28s\n" + " COGL_DISABLE_GL_EXTENSIONS: %s\n" + " COGL_OVERRIDE_GL_VERSION: %s\n", + _("Additional environment variables:"), + _("Comma-separated list of GL extensions to pretend are " + "disabled"), + _("Override the GL version that Cogl will assume the driver " + "supports")); exit (1); } else diff --git a/cogl/cogl-gpu-info.c b/cogl/cogl-gpu-info.c index 53e5bb246..8e64d04b6 100644 --- a/cogl/cogl-gpu-info.c +++ b/cogl/cogl-gpu-info.c @@ -482,7 +482,7 @@ _cogl_gpu_info_init (CoglContext *ctx, int i; strings.renderer_string = (const char *) ctx->glGetString (GL_RENDERER); - strings.version_string = (const char *) ctx->glGetString (GL_VERSION); + strings.version_string = _cogl_context_get_gl_version (ctx); strings.vendor_string = (const char *) ctx->glGetString (GL_VENDOR); /* Determine the driver package */ diff --git a/cogl/driver/gl/cogl-gl.c b/cogl/driver/gl/cogl-gl.c index 3976d5a6f..fed873771 100644 --- a/cogl/driver/gl/cogl-gl.c +++ b/cogl/driver/gl/cogl-gl.c @@ -228,7 +228,7 @@ _cogl_get_gl_version (CoglContext *ctx, int major = 0, minor = 0; /* Get the OpenGL version number */ - if ((version_string = (const char *) ctx->glGetString (GL_VERSION)) == NULL) + if ((version_string = _cogl_context_get_gl_version (ctx)) == NULL) return FALSE; /* Extract the major number */ @@ -276,7 +276,7 @@ check_gl_version (CoglContext *ctx, if (COGL_CHECK_GL_VERSION (major, minor, 1, 3)) return TRUE; - gl_extensions = (const char*) ctx->glGetString (GL_EXTENSIONS); + gl_extensions = _cogl_context_get_gl_extensions (ctx); /* OpenGL 1.2 is only supported if we have the multitexturing extension */ @@ -335,8 +335,8 @@ _cogl_driver_update_features (CoglContext *ctx, " GL_EXTENSIONS: %s", ctx->glGetString (GL_VENDOR), ctx->glGetString (GL_RENDERER), - ctx->glGetString (GL_VERSION), - ctx->glGetString (GL_EXTENSIONS)); + _cogl_context_get_gl_version (ctx), + _cogl_context_get_gl_extensions (ctx)); _cogl_get_gl_version (ctx, &gl_major, &gl_minor); @@ -352,7 +352,7 @@ _cogl_driver_update_features (CoglContext *ctx, if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 1, 4)) COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_MIRRORED_REPEAT, TRUE); - gl_extensions = (const char *)ctx->glGetString (GL_EXTENSIONS); + gl_extensions = _cogl_context_get_gl_extensions (ctx); _cogl_feature_check_ext_functions (ctx, gl_major, diff --git a/cogl/driver/gles/cogl-gles.c b/cogl/driver/gles/cogl-gles.c index 9e46d12da..417fee521 100644 --- a/cogl/driver/gles/cogl-gles.c +++ b/cogl/driver/gles/cogl-gles.c @@ -182,12 +182,12 @@ _cogl_driver_update_features (CoglContext *context, " GL_EXTENSIONS: %s", context->glGetString (GL_VENDOR), context->glGetString (GL_RENDERER), - context->glGetString (GL_VERSION), - context->glGetString (GL_EXTENSIONS)); + _cogl_context_get_gl_version (context), + _cogl_context_get_gl_extensions (context)); _cogl_gpu_info_init (context, &context->gpu); - gl_extensions = (const char*) context->glGetString (GL_EXTENSIONS); + gl_extensions = _cogl_context_get_gl_extensions (context); _cogl_feature_check_ext_functions (context, -1 /* GL major version */, diff --git a/cogl/winsys/cogl-winsys-wgl.c b/cogl/winsys/cogl-winsys-wgl.c index 61cd335c2..418e7286c 100644 --- a/cogl/winsys/cogl-winsys-wgl.c +++ b/cogl/winsys/cogl-winsys-wgl.c @@ -580,7 +580,7 @@ get_wgl_extensions_string (HDC dc) extensions isn't supported then we can at least fake it to support the swap control extension */ if (_cogl_check_extension ("WGL_EXT_swap_control", - (char *) ctx->glGetString (GL_EXTENSIONS))) + _cogl_context_get_gl_extensions (ctx))) return "WGL_EXT_swap_control"; return NULL;