fix cogl_context_new crash if fail to connect renderer

If a NULL display is passed to cogl_context_new() then it has to
implicitly create a CoglRenderer and CoglDisplay and propagate any
resulting errors back to the user. Previously the implementation relied
on passing a NULL renderer to cogl_display_new() as the means for
implicitly connecting to a renderer. The problem with this though is
that cogl_display_new() isn't designed to ever return NULL but if it
failed to connect to a renderer automatically it would do and then
cogl_context_new would pass NULL to cogl_display_setup() leading to a
crash.

This patch changes the implementation of cogl_context_new() to now
explicitly create a CoglRenderer and connect to it if a NULL display is
given. This way we can easily propagate any errors. In addition
cogl_display_new has been changed to abort if it fails to implicitly
connect to a renderer due to a NULL renderer argument.

An application needing to gracefully handle problems connecting to a
renderer at runtime should manually instantiate and connect a renderer
passing a GError argument to cogl_renderer_connect.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
This commit is contained in:
Robert Bragg 2012-04-10 19:21:55 +01:00
parent 995f4cd019
commit cc4c578887
2 changed files with 11 additions and 8 deletions

View File

@ -188,7 +188,16 @@ cogl_context_new (CoglDisplay *display,
memset (context->winsys_features, 0, sizeof (context->winsys_features)); memset (context->winsys_features, 0, sizeof (context->winsys_features));
if (!display) if (!display)
display = cogl_display_new (NULL, NULL); {
CoglRenderer *renderer = cogl_renderer_new ();
if (!cogl_renderer_connect (renderer, error))
{
g_free (context);
return NULL;
}
display = cogl_display_new (renderer, NULL);
}
else else
cogl_object_ref (display); cogl_object_ref (display);

View File

@ -91,13 +91,7 @@ cogl_display_new (CoglRenderer *renderer,
display->renderer = cogl_renderer_new (); display->renderer = cogl_renderer_new ();
if (!cogl_renderer_connect (display->renderer, &error)) if (!cogl_renderer_connect (display->renderer, &error))
{ g_error ("Failed to connect to renderer: %s\n", error->message);
g_warning ("Failed to connect renderer: %s\n", error->message);
g_error_free (error);
g_object_unref (display->renderer);
g_slice_free (CoglDisplay, display);
return NULL;
}
display->onscreen_template = onscreen_template; display->onscreen_template = onscreen_template;
if (onscreen_template) if (onscreen_template)