Add error reporting for create_context() failures

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.
This commit is contained in:
Emmanuele Bassi 2010-03-17 17:28:20 +00:00
parent d735ac4807
commit bf7e6ae587
4 changed files with 29 additions and 7 deletions

View 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);

View 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;
}
/**

View 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
{

View 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);