Blob Blame History Raw
From 5c8f7cc3af63cc98a05efec47649f6ab74ca17a0 Mon Sep 17 00:00:00 2001
From: Adel Gadllah <adel.gadllah@gmail.com>
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 <ebassi@gnome.org>
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 @@
 
       <variablelist>
         <varlistentry>
+          <term>CLUTTER_BACKEND</term>
+          <listitem>
+            <para>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:</para>
+            <itemizedlist>
+              <listitem><simpara>x11, for the X11 backend</simpara></listitem>
+              <listitem><simpara>wayland, for the Wayland backend</simpara></listitem>
+              <listitem><simpara>win32, for the Windows backend</simpara></listitem>
+              <listitem><simpara>osx, for the MacOS X backend</simpara></listitem>
+              <listitem><simpara>gsk, for the GDK backend</simpara></listitem>
+              <listitem><simpara>eglnative, for the EGL/KMS backend</simpara></listitem>
+              <listitem><simpara>cex100, for the CEx100 backend</simpara></listitem>
+            </itemizedlist>
+            <para>All of the above options except for the <varname>eglnative</varname>
+            and <varname>cex100</varname> backends also have an input backend.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term>CLUTTER_INPUT_BACKEND</term>
+          <listitem>
+            <para>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:</para>
+            <itemizedlist>
+              <listitem><simpara>tslib</simpara></listitem>
+              <listitem><simpara>evdev</simpara></listitem>
+              <listitem><simpara>null</simpara></listitem>
+            </itemizedlist>
+            <para>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 <varname>eglnative</varname> or the <varname>cex100</varname>
+            windowing system backends.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term>CLUTTER_DRIVER</term>
+          <listitem>
+            <para>Changes the GL driver used when initializing Clutter.
+            The allowed values for this environment variable are:</para>
+            <itemizedlist>
+              <listitem><simpara>gl3, for the GL driver using a 3.2+ core profile</simpara></listitem>
+              <listitem><simpara>gl, for the GL driver using a legacy profile</simpara></listitem>
+              <listitem><simpara>gles2, for the GLES 2.0 driver</simpara></listitem>
+              <listitem><simpara>any, for the default chosen by Cogl</simpara></listitem>
+            </itemizedlist>
+            <para>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.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
           <term>CLUTTER_SCALE</term>
           <listitem>
             <para>Forces the window scaling factor to that value
-- 
2.7.4


From e012c6823f2619d7ce85fb14a773c84b22a5b9fe Mon Sep 17 00:00:00 2001
From: Emmanuele Bassi <ebassi@gnome.org>
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 <ebassi@gnome.org>
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 <tiagomatos@gmail.com>
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 <tiagomatos@gmail.com>
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" <otaylor@fishsoup.net>
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