Add error reporting for create_context() failures
authorEmmanuele Bassi <ebassi@linux.intel.com>
Wed, 17 Mar 2010 17:28:20 +0000 (17:28 +0000)
committerEmmanuele Bassi <ebassi@linux.intel.com>
Wed, 17 Mar 2010 17:40:34 +0000 (17:40 +0000)
We kind of assume that stuff will break well before during the
ClutterBackend::create_context() implementation if we fail to create a
GL context. We do, however, have error reporting in place inside the
Backend API to catch those cases. Unfortunately, since we switched to
lazy initialization of the Stage, there can be a case of GL context
creation failure that still leads to a successful initialization - and a
segmentation fault later on. This is clearly Not Good™.

Let's try to catch a failure in all the places calling create_context()
and report back to the user the error in a meaningful way, before
crashing and burning.

clutter/clutter-backend.c
clutter/clutter-feature.c
clutter/clutter-main.c
clutter/clutter-private.h

index 7c82337..21b93f1 100644 (file)
@@ -424,6 +424,7 @@ ClutterFeatureFlags
 _clutter_backend_get_features (ClutterBackend *backend)
 {
   ClutterBackendClass *klass;
+  GError *error;
 
   g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), 0);
 
@@ -433,8 +434,25 @@ _clutter_backend_get_features (ClutterBackend *backend)
    * GL context first and the ask for features. if the
    * context already exists this should be a no-op
    */
+  error = NULL;
   if (klass->create_context)
-    klass->create_context (backend, NULL);
+    {
+      gboolean res;
+
+      res = klass->create_context (backend, &error);
+      if (!res)
+        {
+          if (error)
+            {
+              g_critical ("Unable to create a context: %s", error->message);
+              g_error_free (error);
+            }
+          else
+            g_critical ("Unable to create a context: unknown error");
+
+          return 0;
+        }
+    }
 
   if (klass->get_features)
     return klass->get_features (backend);
index 4db690e..74bf87b 100644 (file)
@@ -83,8 +83,8 @@ _clutter_features_from_cogl (guint cogl_flags)
   return clutter_flags;
 }
 
-void
-_clutter_feature_init (void)
+gboolean
+_clutter_feature_init (GError **error)
 {
   ClutterMainContext *context;
 
@@ -98,12 +98,13 @@ _clutter_feature_init (void)
     }
 
   if (__features->features_set)
-    return;
+    return TRUE;
 
   context = _clutter_context_get_default ();
 
   /* makes sure we have a GL context; if we have, this is a no-op */
-  _clutter_backend_create_context (context->backend, NULL);
+  if (!_clutter_backend_create_context (context->backend, error))
+    return FALSE;
 
   __features->flags = (_clutter_features_from_cogl (cogl_get_features ())
                     | _clutter_backend_get_features (context->backend));
@@ -111,6 +112,8 @@ _clutter_feature_init (void)
   __features->features_set = TRUE;
 
   CLUTTER_NOTE (MISC, "features checked");
+
+  return TRUE;
 }
 
 /**
index 053b6fc..fcfa33b 100644 (file)
@@ -1534,7 +1534,8 @@ clutter_init_real (GError **error)
   /* this will take care of initializing Cogl's state and
    * query the GL machinery for features
    */
-  _clutter_feature_init ();
+  if (!_clutter_feature_init (error))
+    return CLUTTER_INIT_ERROR_BACKEND;
 
 #ifdef CLUTTER_ENABLE_PROFILE
     {
index b26771a..bf06563 100644 (file)
@@ -270,7 +270,7 @@ ClutterFeatureFlags _clutter_backend_get_features (ClutterBackend *backend);
 gfloat        _clutter_backend_get_units_per_em   (ClutterBackend       *backend,
                                                    PangoFontDescription *font_desc);
 
-void          _clutter_feature_init (void);
+gboolean      _clutter_feature_init (GError **error);
 
 /* Reinjecting queued events for processing */
 void _clutter_process_event (ClutterEvent *event);