diff --git a/clutter/clutter-backend.c b/clutter/clutter-backend.c index 312227352..62f33ec0b 100644 --- a/clutter/clutter-backend.c +++ b/clutter/clutter-backend.c @@ -362,39 +362,73 @@ error: return FALSE; } +static const struct { + const char *driver_name; + const char *driver_desc; + CoglDriver driver_id; +} all_known_drivers[] = { + { "gl3", "OpenGL 3.2 core profile", COGL_DRIVER_GL3 }, + { "gl", "OpenGL legacy profile", COGL_DRIVER_GL }, + { "gles2", "OpenGL ES 2.0", COGL_DRIVER_GLES2 }, + { "any", "Default Cogl driver", COGL_DRIVER_ANY }, +}; + +static char *allowed_drivers; + static gboolean clutter_backend_real_create_context (ClutterBackend *backend, GError **error) { - static const struct { - const char *driver_name; - CoglDriver driver_id; - } known_drivers[] = { - { "GL3", COGL_DRIVER_GL3 }, - { "GL (Legacy)", COGL_DRIVER_GL }, - { "GLES 2.0", COGL_DRIVER_GLES2 }, - { "ANY", COGL_DRIVER_ANY }, - }; - GError *internal_error = NULL; + const char *drivers_list; + char **known_drivers; + gboolean allow_any; int i; - for (i = 0; i < G_N_ELEMENTS (known_drivers); i++) + if (allowed_drivers == NULL) + allowed_drivers = "*"; + + allow_any = strstr (allowed_drivers, "*") != NULL; + + drivers_list = g_getenv ("CLUTTER_DRIVER"); + if (drivers_list == NULL) + drivers_list = allowed_drivers; + + known_drivers = g_strsplit (drivers_list, ",", 0); + + for (i = 0; backend->cogl_context == NULL && known_drivers[i] != NULL; i++) { - CLUTTER_NOTE (BACKEND, "Checking for the %s driver", known_drivers[i].driver_name); + const char *driver_name = known_drivers[i]; + gboolean is_any = g_str_equal (driver_name, "*"); + int j; - if (clutter_backend_do_real_create_context (backend, known_drivers[i].driver_id, &internal_error)) - break; - - if (internal_error) + for (j = 0; j < G_N_ELEMENTS (all_known_drivers); j++) { - CLUTTER_NOTE (BACKEND, "Unable to use the %s driver: %s", - known_drivers[i].driver_name, - internal_error->message); - g_clear_error (&internal_error); + if (!allow_any && !is_any && !strstr (driver_name, all_known_drivers[j].driver_name)) + continue; + + if ((allow_any && is_any) || + (is_any && strstr (allowed_drivers, all_known_drivers[j].driver_name)) || + g_str_equal (all_known_drivers[j].driver_name, driver_name)) + { + CLUTTER_NOTE (BACKEND, "Checking for the %s driver", all_known_drivers[j].driver_desc); + + if (clutter_backend_do_real_create_context (backend, all_known_drivers[j].driver_id, &internal_error)) + break; + + if (internal_error) + { + CLUTTER_NOTE (BACKEND, "Unable to use the %s driver: %s", + all_known_drivers[j].driver_desc, + internal_error->message); + g_clear_error (&internal_error); + } + } } } + g_strfreev (known_drivers); + if (backend->cogl_context == NULL) { if (internal_error != NULL) @@ -402,13 +436,12 @@ clutter_backend_real_create_context (ClutterBackend *backend, else g_set_error_literal (error, CLUTTER_INIT_ERROR, CLUTTER_INIT_ERROR_BACKEND, - _("Unable to initialize the Clutter backend")); + _("Unable to initialize the Clutter backend: no available drivers found.")); return FALSE; } - backend->cogl_source = cogl_glib_source_new (backend->cogl_context, - G_PRIORITY_DEFAULT); + backend->cogl_source = cogl_glib_source_new (backend->cogl_context, G_PRIORITY_DEFAULT); g_source_attach (backend->cogl_source, NULL); return TRUE; diff --git a/doc/reference/running-clutter.xml b/doc/reference/running-clutter.xml index 081174431..2d782b3fa 100644 --- a/doc/reference/running-clutter.xml +++ b/doc/reference/running-clutter.xml @@ -64,6 +64,23 @@ windowing system backends. + + CLUTTER_DRIVER + + Changes the GL driver used when initializing Clutter. + The allowed values for this environment variable are: + + gl3, for the GL driver using a 3.2+ core profile + gl, for the GL driver using a legacy profile + gles2, for the GLES 2.0 driver + any, for the default chosen by Cogl + + The special '*' value can be used to ask Clutter to use the + default list of drivers, e.g. 'CLUTTER_DRIVER=gles2,*' will ask Clutter + to try the GLES 2.0 driver first, and then fall back to the default list + of Cogl drivers. + + CLUTTER_SCALE