From 5c8f7cc3af63cc98a05efec47649f6ab74ca17a0 Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Sun, 26 Jul 2015 11:29:10 +0200 Subject: [PATCH 1/7] backend: Check for a known set of drivers We want to use the Cogl GL3 driver, if possible, and then go through a known list of Cogl drivers, before giving up and using COGL_DRIVER_ANY. Based on original patch from Emmanuele Bassi. We have to create and tear down the whole context when trying out the drivers though because the extension checks do not happen until cogl_context_init. https://bugzilla.gnome.org/show_bug.cgi?id=742678 --- clutter/clutter-backend.c | 69 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/clutter/clutter-backend.c b/clutter/clutter-backend.c index d255eee..0a4ae1a 100644 --- a/clutter/clutter-backend.c +++ b/clutter/clutter-backend.c @@ -257,8 +257,9 @@ clutter_backend_real_font_changed (ClutterBackend *backend) } static gboolean -clutter_backend_real_create_context (ClutterBackend *backend, - GError **error) +clutter_backend_do_real_create_context (ClutterBackend *backend, + CoglDriver driver_id, + GError **error) { ClutterBackendClass *klass; CoglSwapChain *swap_chain; @@ -290,6 +291,7 @@ clutter_backend_real_create_context (ClutterBackend *backend, #endif CLUTTER_NOTE (BACKEND, "Connecting the renderer"); + cogl_renderer_set_driver (backend->cogl_renderer, driver_id); if (!cogl_renderer_connect (backend->cogl_renderer, &internal_error)) goto error; @@ -346,10 +348,6 @@ clutter_backend_real_create_context (ClutterBackend *backend, if (backend->cogl_context == NULL) goto error; - backend->cogl_source = cogl_glib_source_new (backend->cogl_context, - G_PRIORITY_DEFAULT); - g_source_attach (backend->cogl_source, NULL); - /* the display owns the renderer and the swap chain */ cogl_object_unref (backend->cogl_renderer); cogl_object_unref (swap_chain); @@ -372,16 +370,61 @@ error: if (swap_chain != NULL) cogl_object_unref (swap_chain); - if (internal_error != NULL) - g_propagate_error (error, internal_error); - else - g_set_error_literal (error, CLUTTER_INIT_ERROR, - CLUTTER_INIT_ERROR_BACKEND, - _("Unable to initialize the Clutter backend")); - return FALSE; } +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; + int i; + + for (i = 0; i < G_N_ELEMENTS (known_drivers); i++) + { + CLUTTER_NOTE (BACKEND, "Checking for the %s driver", known_drivers[i].driver_name); + + if (clutter_backend_do_real_create_context (backend, known_drivers[i].driver_id, &internal_error)) + break; + + if (internal_error) + { + CLUTTER_NOTE (BACKEND, "Unable to use the %s driver: %s", + known_drivers[i].driver_name, + internal_error->message); + g_clear_error (&internal_error); + } + } + + if (backend->cogl_context == NULL) + { + if (internal_error != NULL) + g_propagate_error (error, internal_error); + else + g_set_error_literal (error, CLUTTER_INIT_ERROR, + CLUTTER_INIT_ERROR_BACKEND, + _("Unable to initialize the Clutter backend")); + + return FALSE; + } + + backend->cogl_source = cogl_glib_source_new (backend->cogl_context, + G_PRIORITY_DEFAULT); + g_source_attach (backend->cogl_source, NULL); + + return TRUE; +} + static void clutter_backend_real_ensure_context (ClutterBackend *backend, ClutterStage *stage) -- 2.7.4 From 6b9281ac7da725a1861a6418c24fcb6371d3c72b Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 9 Dec 2015 12:45:12 +0000 Subject: [PATCH 2/7] backend: Allow overriding the Cogl drivers chain We have an hardcoded list of drivers we have to go through when creating a Cogl context. Some platforms may expose those drivers, but not be the preferred ones. In order to allow users and system integrators to override the list of drivers, we should crib the same approach used by GDK, and have an environment variable with a list of drivers to try. The new environment variable is called `CLUTTER_DRIVER` and accepts a comma-separated list of driver names, which will be tested in sequence until one succeeds. There's also an additional '*' token which is used to ask Clutter to fall back to the internally defined preferred list of drivers. https://bugzilla.gnome.org/show_bug.cgi?id=742678 --- clutter/clutter-backend.c | 79 ++++++++++++++++++++++--------- doc/reference/clutter/running-clutter.xml | 55 +++++++++++++++++++++ 2 files changed, 111 insertions(+), 23 deletions(-) diff --git a/clutter/clutter-backend.c b/clutter/clutter-backend.c index 0a4ae1a..9ee3659 100644 --- a/clutter/clutter-backend.c +++ b/clutter/clutter-backend.c @@ -373,39 +373,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++) - { - CLUTTER_NOTE (BACKEND, "Checking for the %s driver", known_drivers[i].driver_name); + 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; - if (clutter_backend_do_real_create_context (backend, known_drivers[i].driver_id, &internal_error)) - break; + known_drivers = g_strsplit (drivers_list, ",", 0); - if (internal_error) + for (i = 0; backend->cogl_context == NULL && known_drivers[i] != NULL; i++) + { + const char *driver_name = known_drivers[i]; + gboolean is_any = g_str_equal (driver_name, "*"); + int j; + + 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) @@ -413,13 +447,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/clutter/running-clutter.xml b/doc/reference/clutter/running-clutter.xml index 9d1dc63..2d782b3 100644 --- a/doc/reference/clutter/running-clutter.xml +++ b/doc/reference/clutter/running-clutter.xml @@ -27,6 +27,61 @@ + CLUTTER_BACKEND + + Changes the windowing system backend used by Clutter. + The allowed values for this environment variable depend on + the configuration options used when compiling Clutter. The + available values are: + + x11, for the X11 backend + wayland, for the Wayland backend + win32, for the Windows backend + osx, for the MacOS X backend + gsk, for the GDK backend + eglnative, for the EGL/KMS backend + cex100, for the CEx100 backend + + All of the above options except for the eglnative + and cex100 backends also have an input backend. + + + + CLUTTER_INPUT_BACKEND + + Changes the input backend used by Clutter. + The allowed values for this environment variable depend on + the configuration options used when compiling Clutter. The + available values are: + + tslib + evdev + null + + This environment variable is only useful for setting the input + backend when using a windowing system backend that does not have an + input API, like the eglnative or the cex100 + 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 Forces the window scaling factor to that value -- 2.7.4 From e012c6823f2619d7ce85fb14a773c84b22a5b9fe Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 9 Dec 2015 14:26:28 +0000 Subject: [PATCH 3/7] Add a configuration option for deciding the Cogl drivers to use Using environment variables only is not convenient for all platforms, and in some cases it's beneficial to decide the default driver when building Clutter. Cogl already has a similar configuration switch, and since Clutter is overriding the default Cogl behaviour, it should offer the same mechanism. https://bugzilla.gnome.org/show_bug.cgi?id=742678 --- clutter/clutter-backend.c | 2 +- configure.ac | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/clutter/clutter-backend.c b/clutter/clutter-backend.c index 9ee3659..3faae3a 100644 --- a/clutter/clutter-backend.c +++ b/clutter/clutter-backend.c @@ -397,7 +397,7 @@ clutter_backend_real_create_context (ClutterBackend *backend, int i; if (allowed_drivers == NULL) - allowed_drivers = "*"; + allowed_drivers = CLUTTER_DRIVERS; allow_any = strstr (allowed_drivers, "*") != NULL; diff --git a/configure.ac b/configure.ac index 0a62633..fe7e085 100644 --- a/configure.ac +++ b/configure.ac @@ -534,6 +534,13 @@ dnl other tools such as glib-mkenums and gir-scanner don't end up dnl using the define also. AC_DEFINE([COGL_ENABLE_EXPERIMENTAL_2_0_API], [1], [Can use Cogl 2.0 API internally]) +AC_ARG_WITH([default-drivers], + [AS_HELP_STRING([--with-default-drivers=DRIVER], [Comma-separated list of Cogl drivers to use])], + [clutter_drivers=$withval], + [clutter_drivers="*"]) + +AC_DEFINE_UNQUOTED([CLUTTER_DRIVERS], ["$clutter_drivers"], [List of Cogl drivers]) + dnl strip leading spaces CLUTTER_BACKENDS=${CLUTTER_BACKENDS#* } AC_SUBST(CLUTTER_BACKENDS) @@ -1274,6 +1281,8 @@ else echo " Input backends: ${CLUTTER_INPUT_BACKENDS} (WARNING: Experimental backends enabled)" fi +echo " Cogl drivers: $clutter_drivers" + if test "x$SUPPORT_X11" = "x1"; then echo "" echo " - X11 backend options:" -- 2.7.4 From 486a1a8a0ddc40c7782c0b0508768b3d8baa12db Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Thu, 10 Dec 2015 16:52:45 +0000 Subject: [PATCH 4/7] Allow overriding the list of Cogl drivers via configuration file Clutter has a configuration file that can be used to override various settings, including the ones from environment variables. --- clutter/clutter-backend-private.h | 2 ++ clutter/clutter-backend.c | 8 +++++++- clutter/clutter-main.c | 11 +++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/clutter/clutter-backend-private.h b/clutter/clutter-backend-private.h index a9e7ae2..801548b 100644 --- a/clutter/clutter-backend-private.h +++ b/clutter/clutter-backend-private.h @@ -142,6 +142,8 @@ gint32 _clutter_backend_get_units_serial (Clutter PangoDirection _clutter_backend_get_keymap_direction (ClutterBackend *backend); +void clutter_set_allowed_drivers (const char *drivers); + G_END_DECLS #endif /* __CLUTTER_BACKEND_PRIVATE_H__ */ diff --git a/clutter/clutter-backend.c b/clutter/clutter-backend.c index 3faae3a..34c088d 100644 --- a/clutter/clutter-backend.c +++ b/clutter/clutter-backend.c @@ -384,7 +384,7 @@ static const struct { { "any", "Default Cogl driver", COGL_DRIVER_ANY }, }; -static char *allowed_drivers; +static const char *allowed_drivers; static gboolean clutter_backend_real_create_context (ClutterBackend *backend, @@ -1492,3 +1492,9 @@ _clutter_backend_get_keymap_direction (ClutterBackend *backend) return PANGO_DIRECTION_NEUTRAL; } + +void +clutter_set_allowed_drivers (const char *drivers) +{ + allowed_drivers = g_strdup (drivers); +} diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index 444ceba..11d5150 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -229,6 +229,17 @@ clutter_config_read_from_key_file (GKeyFile *keyfile) if (!g_key_file_has_group (keyfile, ENVIRONMENT_GROUP)) return; + str_value = + g_key_file_get_string (keyfile, ENVIRONMENT_GROUP, + "Drivers", + &key_error); + if (key_error != NULL) + g_clear_error (&key_error); + else + clutter_set_allowed_drivers (str_value); + + g_free (str_value); + bool_value = g_key_file_get_boolean (keyfile, ENVIRONMENT_GROUP, "ShowFps", -- 2.7.4 From f09847882c87b94225d14c058a34bb7faedacd09 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Thu, 11 Aug 2016 15:35:59 +0200 Subject: [PATCH 5/7] Make clutter_set_allowed_drivers() public We'll need to call it from mutter. --- clutter/clutter-backend-private.h | 2 -- clutter/clutter-backend.h | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/clutter/clutter-backend-private.h b/clutter/clutter-backend-private.h index 801548b..a9e7ae2 100644 --- a/clutter/clutter-backend-private.h +++ b/clutter/clutter-backend-private.h @@ -142,8 +142,6 @@ gint32 _clutter_backend_get_units_serial (Clutter PangoDirection _clutter_backend_get_keymap_direction (ClutterBackend *backend); -void clutter_set_allowed_drivers (const char *drivers); - G_END_DECLS #endif /* __CLUTTER_BACKEND_PRIVATE_H__ */ diff --git a/clutter/clutter-backend.h b/clutter/clutter-backend.h index e14d5d2..c7dfc24 100644 --- a/clutter/clutter-backend.h +++ b/clutter/clutter-backend.h @@ -78,6 +78,9 @@ CLUTTER_AVAILABLE_IN_1_8 CoglContext * clutter_backend_get_cogl_context (ClutterBackend *backend); #endif +CLUTTER_AVAILABLE_IN_ALL +void clutter_set_allowed_drivers (const char *drivers); + G_END_DECLS #endif /* __CLUTTER_BACKEND_H__ */ -- 2.7.4 From aa79960d2e79141f0caaa27a48468ed67acd30b2 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Thu, 11 Aug 2016 15:50:30 +0200 Subject: [PATCH 6/7] backend: Revert to using the gl driver by default instead of gl3 Some applications (e.g. totem) don't work well (or at all) with the gl3 driver without modifications and it's safer to keep clutter behaving the same as it did when RHEL 7 launched so let's switch the default driver back to gl. --- clutter/clutter-backend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clutter/clutter-backend.c b/clutter/clutter-backend.c index 34c088d..15a1d05 100644 --- a/clutter/clutter-backend.c +++ b/clutter/clutter-backend.c @@ -378,8 +378,8 @@ static const struct { 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 }, + { "gl3", "OpenGL 3.2 core profile", COGL_DRIVER_GL3 }, { "gles2", "OpenGL ES 2.0", COGL_DRIVER_GLES2 }, { "any", "Default Cogl driver", COGL_DRIVER_ANY }, }; -- 2.7.4 From 03db9fc0b5035c1c74132b6f33468e8670802558 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Wed, 29 Jun 2016 17:03:46 -0400 Subject: [PATCH 7/7] Don't create the Cogl GLib source multiple times Since the check for backend->cogl_context was accidentally moved to clutter_backend_do_real_create_context, the Glib source that is created at the end of clutter_backend_do_create_context() is created and added each time create_context() is called, though create_context() is supposed to be idempotent. https://bugzilla.gnome.org/show_bug.cgi?id=768243 --- clutter/clutter-backend.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clutter/clutter-backend.c b/clutter/clutter-backend.c index 15a1d05..56f2bf2 100644 --- a/clutter/clutter-backend.c +++ b/clutter/clutter-backend.c @@ -265,9 +265,6 @@ clutter_backend_do_real_create_context (ClutterBackend *backend, CoglSwapChain *swap_chain; GError *internal_error; - if (backend->cogl_context != NULL) - return TRUE; - klass = CLUTTER_BACKEND_GET_CLASS (backend); swap_chain = NULL; @@ -396,6 +393,9 @@ clutter_backend_real_create_context (ClutterBackend *backend, gboolean allow_any; int i; + if (backend->cogl_context != NULL) + return TRUE; + if (allowed_drivers == NULL) allowed_drivers = CLUTTER_DRIVERS; -- 2.7.4