diff options
author | Emmanuele Bassi <ebassi@linux.intel.com> | 2011-11-04 15:50:47 +0000 |
---|---|---|
committer | Emmanuele Bassi <ebassi@linux.intel.com> | 2011-11-10 14:42:40 +0000 |
commit | a918ac92cb2278a8ebbc118f55443e4974dd696f (patch) | |
tree | 94e92b2455402b23777e8a17b7fae9703eaa2c85 /clutter/clutter-backend.c | |
parent | 5b1b936491c89b75c211584e77946d3dea0c5f81 (diff) | |
download | clutter-a918ac92cb2278a8ebbc118f55443e4974dd696f.tar.gz |
backend: Provide a default create_context()
Since we use Cogl for the context creation we can now provide a default
context creation that should just work, plus a couple of hooks to allow
plugging into the creation sequence for platforms supported by Cogl that
require special handling — like foreign displays or alpha-enabled swap
chains.
The various backends have now two choices: either replace the
create_context() in its entirety, or plug themselves into the default
context creation.
Diffstat (limited to 'clutter/clutter-backend.c')
-rw-r--r-- | clutter/clutter-backend.c | 114 |
1 files changed, 111 insertions, 3 deletions
diff --git a/clutter/clutter-backend.c b/clutter/clutter-backend.c index 39846e1c9..d97718793 100644 --- a/clutter/clutter-backend.c +++ b/clutter/clutter-backend.c @@ -226,6 +226,115 @@ clutter_backend_real_font_changed (ClutterBackend *backend) CLUTTER_NOTE (BACKEND, "Units per em: %.2f", priv->units_per_em); } +static gboolean +clutter_backend_real_create_context (ClutterBackend *backend, + GError **error) +{ + ClutterBackendClass *klass; + CoglSwapChain *swap_chain; + GError *internal_error; + + if (backend->cogl_context != NULL) + return TRUE; + + klass = CLUTTER_BACKEND_GET_CLASS (backend); + + swap_chain = NULL; + internal_error = NULL; + + CLUTTER_NOTE (BACKEND, "Creating Cogl renderer"); + if (klass->get_renderer != NULL) + backend->cogl_renderer = klass->get_renderer (backend, &internal_error); + else + backend->cogl_renderer = cogl_renderer_new (); + + if (backend->cogl_renderer == NULL) + goto error; + + CLUTTER_NOTE (BACKEND, "Connecting the renderer"); + if (!cogl_renderer_connect (backend->cogl_renderer, &internal_error)) + goto error; + + CLUTTER_NOTE (BACKEND, "Creating Cogl swap chain"); + swap_chain = cogl_swap_chain_new (); + + CLUTTER_NOTE (BACKEND, "Creating Cogl display"); + if (klass->get_display != NULL) + { + backend->cogl_display = klass->get_display (backend, + backend->cogl_renderer, + swap_chain, + &internal_error); + } + else + { + CoglOnscreenTemplate *tmpl; + gboolean res; + + tmpl = cogl_onscreen_template_new (swap_chain); + + /* XXX: I have some doubts that this is a good design. + * + * Conceptually should we be able to check an onscreen_template + * without more details about the CoglDisplay configuration? + */ + res = cogl_renderer_check_onscreen_template (backend->cogl_renderer, + tmpl, + &internal_error); + + if (!res) + goto error; + + backend->cogl_display = cogl_display_new (backend->cogl_renderer, tmpl); + + /* the display owns the template */ + cogl_object_unref (tmpl); + } + + if (backend->cogl_display == NULL) + goto error; + + CLUTTER_NOTE (BACKEND, "Setting up the display"); + if (!cogl_display_setup (backend->cogl_display, &internal_error)) + goto error; + + CLUTTER_NOTE (BACKEND, "Creating the Cogl context"); + backend->cogl_context = cogl_context_new (backend->cogl_display, &internal_error); + if (backend->cogl_context == NULL) + goto error; + + /* the display owns the renderer and the swap chain */ + cogl_object_unref (backend->cogl_renderer); + cogl_object_unref (swap_chain); + + return TRUE; + +error: + if (backend->cogl_display != NULL) + { + cogl_object_unref (backend->cogl_display); + backend->cogl_display = NULL; + } + + if (backend->cogl_renderer != NULL) + { + cogl_object_unref (backend->cogl_renderer); + backend->cogl_renderer = NULL; + } + + 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 void clutter_backend_real_ensure_context (ClutterBackend *backend, ClutterStage *stage) @@ -429,6 +538,7 @@ clutter_backend_class_init (ClutterBackendClass *klass) klass->init_events = clutter_backend_real_init_events; klass->translate_event = clutter_backend_real_translate_event; + klass->create_context = clutter_backend_real_create_context; klass->ensure_context = clutter_backend_real_ensure_context; klass->redraw = clutter_backend_real_redraw; } @@ -546,10 +656,8 @@ _clutter_backend_create_context (ClutterBackend *backend, ClutterBackendClass *klass; klass = CLUTTER_BACKEND_GET_CLASS (backend); - if (klass->create_context) - return klass->create_context (backend, error); - return TRUE; + return klass->create_context (backend, error); } void |